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