prepped for more streams, vue3 store not reactive when pushing to rules array, wonky fix
This commit is contained in:
parent
400b2bde87
commit
b8fa676e16
8 changed files with 131 additions and 82 deletions
|
|
@ -2,7 +2,6 @@
|
||||||
<div
|
<div
|
||||||
id="app"
|
id="app"
|
||||||
:class="[
|
:class="[
|
||||||
stream,
|
|
||||||
{ mobile: isMobile }
|
{ mobile: isMobile }
|
||||||
]">
|
]">
|
||||||
<Styles />
|
<Styles />
|
||||||
|
|
@ -34,7 +33,6 @@ export default {
|
||||||
return {
|
return {
|
||||||
api: api,
|
api: api,
|
||||||
zulipClient: null,
|
zulipClient: null,
|
||||||
stream: null,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -49,13 +47,11 @@ export default {
|
||||||
this.getStreams();
|
this.getStreams();
|
||||||
|
|
||||||
this.$router.afterEach((to) => {
|
this.$router.afterEach((to) => {
|
||||||
this.$store.commit("setCurStream", to.path.replace("/", ""))
|
|
||||||
this.stream = to.path.replace("/", "")
|
|
||||||
if (this.stream != "") {
|
|
||||||
this.setUpDoc(this.stream);
|
|
||||||
} else {
|
|
||||||
this.$store.commit("setContents", []);
|
this.$store.commit("setContents", []);
|
||||||
this.$store.commit("setRules", []);
|
this.$store.commit("setRules", []);
|
||||||
|
this.$store.commit("setCurStream", to.path.replace("/", ""))
|
||||||
|
if (this.currentStream != "") {
|
||||||
|
this.setUpDoc(this.currentStream);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -64,30 +60,30 @@ export default {
|
||||||
checkIfMobile: () => window.innerWidth < 700,
|
checkIfMobile: () => window.innerWidth < 700,
|
||||||
|
|
||||||
getStreams() {
|
getStreams() {
|
||||||
api
|
api.zulip.init().then(client => {
|
||||||
.zulip
|
|
||||||
.init()
|
|
||||||
.then(client => {
|
|
||||||
this.zulipClient = client
|
this.zulipClient = client
|
||||||
api
|
api.zulip.getStreams(client).then(result => {
|
||||||
.zulip
|
this.$store.commit( 'setStreams',
|
||||||
.getStreams(client)
|
result.streams
|
||||||
.then(result => {
|
.filter(s => s.name.startsWith(this.pubStr))
|
||||||
this
|
|
||||||
.$store
|
|
||||||
.commit( 'setStreams',
|
|
||||||
result
|
|
||||||
.streams
|
|
||||||
.filter(s =>
|
|
||||||
s.name.startsWith(this.pubStr)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
api.zulip.listen(this.zulipClient, this.eventHandler)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
setUpDoc(stream) {
|
setUpDoc(stream) {
|
||||||
|
|
||||||
|
api.zulip.getSubs(this.zulipClient).then(result => {
|
||||||
|
if (
|
||||||
|
!result.subscriptions
|
||||||
|
.map(s => s.name)
|
||||||
|
.includes(this.currentStream)
|
||||||
|
) {
|
||||||
|
api.zulip.addSub(this.zulipClient, this.currentStream)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
api.zulip.getMsgs(this.zulipClient, stream, "content").then((result) => {
|
api.zulip.getMsgs(this.zulipClient, stream, "content").then((result) => {
|
||||||
for (let m = 0; m < result.messages.length; m++) {
|
for (let m = 0; m < result.messages.length; m++) {
|
||||||
const message = result.messages[m]
|
const message = result.messages[m]
|
||||||
|
|
@ -99,8 +95,6 @@ export default {
|
||||||
this.$store.commit("setRules", result.messages);
|
this.$store.commit("setRules", result.messages);
|
||||||
});
|
});
|
||||||
|
|
||||||
api.zulip.listen(this.zulipClient, this.eventHandler)
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
eventHandler(event) {
|
eventHandler(event) {
|
||||||
|
|
@ -125,7 +119,7 @@ export default {
|
||||||
case 'update_message':
|
case 'update_message':
|
||||||
this.$store.commit('editMessage', {
|
this.$store.commit('editMessage', {
|
||||||
mid: event.message_id,
|
mid: event.message_id,
|
||||||
content: event.content
|
content: event.rendered_content
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -192,17 +186,27 @@ main {
|
||||||
section {
|
section {
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-left: 1em;
|
/* margin-left: 1em; */
|
||||||
min-width: 500px;
|
padding: 1em;
|
||||||
|
min-width: 800px;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
background: lightgray;
|
||||||
|
}
|
||||||
|
section p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
section .title {
|
section .title {
|
||||||
|
display: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 1em;
|
top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.title { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<section class="content">
|
<section class="content">
|
||||||
<p class="title">{{ $.type.name }}</p>
|
<p class="title">{{ $.type.name }}</p>
|
||||||
<div class="body">
|
<div
|
||||||
|
class="body"
|
||||||
|
:class="currentStream"
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-for="message in contents"
|
v-for="message in contents"
|
||||||
:key="message.id"
|
:key="message.id"
|
||||||
|
|
@ -27,7 +30,8 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
'contents',
|
'contents',
|
||||||
'rules'
|
'rules',
|
||||||
|
'currentStream'
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -36,7 +40,11 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
section {
|
.content {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
|
background: unset;
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
.title { display: none; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<code
|
<div
|
||||||
class="rule"
|
class="rule"
|
||||||
:style="rule.rules"
|
:style="rule.rules"
|
||||||
>
|
>
|
||||||
<p :title="toEmojiCode(rule.className)">{{ rule.className }} {</p>
|
<p :title="toEmojiCode(rule.className)">{{ rule.className }} {</p>
|
||||||
<p v-for="dec in rule.rules" :key="dec"> {{ dec }}</p>
|
<p v-for="dec in rule.rules" :key="dec"> {{ dec }}</p>
|
||||||
<p>}</p>
|
<p>}</p>
|
||||||
</code>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,20 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { mapState } from 'vuex';
|
||||||
import emoji from "../../mixins/emoji";
|
import emoji from "../../mixins/emoji";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Styles",
|
name: "Styles",
|
||||||
mixins: [emoji],
|
mixins: [emoji],
|
||||||
computed: {
|
computed: {
|
||||||
rules() {
|
...mapState([
|
||||||
return this.$store.state.rules;
|
'rules'
|
||||||
|
]),
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
data() {
|
||||||
data: function () {
|
|
||||||
return {
|
return {
|
||||||
el: null,
|
el: null,
|
||||||
htmlTags: [
|
|
||||||
'section',
|
|
||||||
'p',
|
|
||||||
'a',
|
|
||||||
'span',
|
|
||||||
'code',
|
|
||||||
'ul',
|
|
||||||
'li',
|
|
||||||
'and so on'
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -38,22 +31,24 @@ export default {
|
||||||
});
|
});
|
||||||
styles += "}";
|
styles += "}";
|
||||||
});
|
});
|
||||||
console.log(styles)
|
|
||||||
return styles;
|
return styles;
|
||||||
},
|
},
|
||||||
insertStyleElement() {
|
createStyleElement() {
|
||||||
var style = document.createElement("style");
|
var style = document.createElement("style");
|
||||||
style.innerText = this.generateStyleRules();
|
style.innerText = this.generateStyleRules();
|
||||||
return style;
|
return style;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted() {
|
||||||
this.el = document.head.appendChild(this.insertStyleElement());
|
this.el = this.createStyleElement()
|
||||||
|
document.head.appendChild(this.el)
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
rules() {
|
rules() {
|
||||||
let style = this.insertStyleElement();
|
console.log('rules!')
|
||||||
this.el.parentNode.replaceChild(style, this.el);
|
const newStyle = this.createStyleElement()
|
||||||
|
document.head.replaceChild(newStyle, this.el)
|
||||||
|
this.el = newStyle
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,21 @@ export default {
|
||||||
...mapState([
|
...mapState([
|
||||||
'rules',
|
'rules',
|
||||||
])
|
])
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
rules() {
|
||||||
|
console.log('rules')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.rules {
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.rules { display: none; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -21,6 +21,8 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
div {
|
||||||
|
}
|
||||||
div p {
|
div p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,10 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
section {
|
.streams {
|
||||||
min-width: 6em;
|
min-width: 10em;
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
.streams { display: none; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,24 +1,28 @@
|
||||||
/*eslint no-unused-vars: "off"*/
|
/*eslint no-unused-vars: "off"*/
|
||||||
/*eslint no-undef: "off"*/
|
/*eslint no-undef: "off"*/
|
||||||
|
|
||||||
|
// import Vue from 'vue'
|
||||||
import { createStore } from 'vuex'
|
import { createStore } from 'vuex'
|
||||||
import emoji from "../mixins/emoji";
|
import emoji from "../mixins/emoji"
|
||||||
import { stripHtml } from "string-strip-html";
|
import { stripHtml } from "string-strip-html"
|
||||||
|
|
||||||
var EmojiConvertor = require('emoji-js');
|
var EmojiConvertor = require('emoji-js');
|
||||||
var emojiConv = new EmojiConvertor();
|
var emojiConv = new EmojiConvertor();
|
||||||
|
|
||||||
let toCSS = (message, currentStream) => {
|
let toCSS = (message, currentStream) => {
|
||||||
|
// console.log(message)
|
||||||
let className = "",
|
let className = "",
|
||||||
emoji_code = "",
|
emoji_code = "",
|
||||||
rules = [],
|
rules = [],
|
||||||
parentClassName = currentStream
|
parentClassName = currentStream,
|
||||||
|
id = message.id
|
||||||
|
|
||||||
// let regex = /[/s]?(?<selector>.+)\s*\n?{\n?(?<prop>[\s\w.~:>-]+\s*:\s*.+;?\n?)*\n?}/gm
|
// let regex = /[/s]?(?<selector>.+)\s*\n?{\n?(?<prop>[\s\w.~:>-]+\s*:\s*.+;?\n?)*\n?}/gm
|
||||||
let regex = /[/s]?(?<selector>.+)\s*\n?{\n?(?<props>(.*;\n?)+)}/gm
|
let regex = /[/s]?(?<selector>.+)\s*\n?{\n?(?<props>(.*;\n?)+)}/gm
|
||||||
let content = stripHtml(message.content).result;
|
let content = stripHtml(message.content).result;
|
||||||
let results = content.matchAll(regex);
|
let results = content.matchAll(regex);
|
||||||
results = Array.from(results);
|
results = Array.from(results);
|
||||||
|
// console.log(results)
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
className = emojiConv.replace_colons(results[0]['groups']['selector']);
|
className = emojiConv.replace_colons(results[0]['groups']['selector']);
|
||||||
if (emoji.methods.containsEmoji(className)) {
|
if (emoji.methods.containsEmoji(className)) {
|
||||||
|
|
@ -26,7 +30,8 @@ let toCSS = (message, currentStream) => {
|
||||||
}
|
}
|
||||||
rules = results[0]['groups']['props'].split("\n");
|
rules = results[0]['groups']['props'].split("\n");
|
||||||
rules = rules.filter((rule) => validateRule(rule))
|
rules = rules.filter((rule) => validateRule(rule))
|
||||||
return { className, emoji_code, rules, parentClassName };
|
// console.log(className, emoji_code, rules, parentClassName, id)
|
||||||
|
return { className, emoji_code, rules, parentClassName, id };
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -84,11 +89,13 @@ export default createStore({
|
||||||
},
|
},
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
|
|
||||||
setMobile : (state, mobile) => state.isMobile = mobile,
|
setMobile : (state, mobile) => state.isMobile = mobile,
|
||||||
setStreams : (state, streams) => state.streams = streams,
|
setStreams : (state, streams) => state.streams = streams,
|
||||||
setCurStream : (state, stream) => state.currentStream = stream,
|
setCurStream : (state, stream) => state.currentStream = stream,
|
||||||
|
setContents: (state, contents) => state.contents = contents,
|
||||||
addMessage: (state, message) => {
|
addMessage: (state, message) => {
|
||||||
|
if (message.display_recipient == state.currentStream) {
|
||||||
if (message.content.startsWith('@_**')) {
|
if (message.content.startsWith('@_**')) {
|
||||||
handleMDReply(message)
|
handleMDReply(message)
|
||||||
} else if (
|
} else if (
|
||||||
|
|
@ -98,11 +105,6 @@ export default createStore({
|
||||||
handleHTMLReply(message)
|
handleHTMLReply(message)
|
||||||
}
|
}
|
||||||
state.contents.push(message)
|
state.contents.push(message)
|
||||||
},
|
|
||||||
editMessage: (state, { mid, content }) => {
|
|
||||||
const message = state.contents.find(m => m.id == mid)
|
|
||||||
if (message) {
|
|
||||||
message.content = content
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteMessage: (state, mid) => {
|
deleteMessage: (state, mid) => {
|
||||||
|
|
@ -123,7 +125,6 @@ export default createStore({
|
||||||
message.reactions.splice(message.reactions.indexOf(reaction), 1)
|
message.reactions.splice(message.reactions.indexOf(reaction), 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setRules: (state, rules) => {
|
setRules: (state, rules) => {
|
||||||
state.rules = rules.reduce((acc, cur) => {
|
state.rules = rules.reduce((acc, cur) => {
|
||||||
let rule = toCSS(cur, state.currentStream);
|
let rule = toCSS(cur, state.currentStream);
|
||||||
|
|
@ -133,12 +134,35 @@ export default createStore({
|
||||||
return acc
|
return acc
|
||||||
}, [])
|
}, [])
|
||||||
},
|
},
|
||||||
|
|
||||||
addRule: (state, rule) => {
|
addRule: (state, rule) => {
|
||||||
if (toCSS(rule) !== null) {
|
if (toCSS(rule) !== null) {
|
||||||
state.rules.push(toCSS(rule))
|
state.rules.push(toCSS(rule, state.currentStream))
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
editMessage: (state, { mid, content }) => {
|
||||||
|
const message = state.contents.find(m => m.id == mid)
|
||||||
|
const rule = state.rules.find(r => r.id == mid)
|
||||||
|
if (message) {
|
||||||
|
message.content = content
|
||||||
|
if (message.content.startsWith('@_**')) {
|
||||||
|
handleMDReply(message)
|
||||||
|
} else if (
|
||||||
|
message.content.includes('user-mention') &&
|
||||||
|
message.content.includes('blockquote')
|
||||||
|
) {
|
||||||
|
handleHTMLReply(message)
|
||||||
}
|
}
|
||||||
|
} else if (rule) {
|
||||||
|
const newRules = [...state.rules, ...[toCSS({
|
||||||
|
id: mid, content: content,
|
||||||
|
}, state.currentStream)]]
|
||||||
|
state.rules = newRules
|
||||||
|
|
||||||
|
// state.rules[state.rules.indexOf(rule)] = toCSS({
|
||||||
|
// id: mid, content: content,
|
||||||
|
// }, state.currentStream)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -146,6 +170,7 @@ export default createStore({
|
||||||
},
|
},
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
|
rules: state => state.rules
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue