Merge branch 'master' of github.com:hackersanddesigners/chatty-pub

merge with hrk
This commit is contained in:
كارل مبارك 2021-07-09 09:44:15 +02:00
commit 63bbd523c7
6 changed files with 146 additions and 65 deletions

View file

@ -1,43 +1,44 @@
<template>
<div :class="[ 'body', topic.title ]">
<h3
@click="desiresContent = !desiresContent"
class="header"
>
<span class="expandToggle">{{ desiresContent ? '▼ ' : '► '}}</span>
<div :class="['body', topic.title]">
<h3 @click="desiresContent = !desiresContent" class="header">
<span class="expandToggle" v-html="toggleSymbol"></span>
<span>{{ topic.title }}</span>
</h3>
<div v-if="desiresContent">
<span
v-for="message in topic.messages"
:key="message.id"
>
<Message
:message="message"
/>
<span>&nbsp;</span>
</h3>
<div v-if="desiresContent || print">
<span v-for="message in topic.messages" :key="message.id">
<Message :message="message" :show_message_data="show_message_data" />
<span>&nbsp;</span>
</span>
</div>
<div style="float: none"><div style="page-break-after: always"></div></div>
</div>
</template>
<script>
import Message from './Message'
import Message from "./Message";
export default {
name: 'Chapter',
components: {
name: "Chapter",
components: {
Message,
},
data() {
return {
desiresContent: false,
}
};
},
props: [
'topic',
],
}
props: ["topic", "print", "show_message_data"],
computed: {
toggleSymbol() {
let r = "";
if (!this.print) {
r = this.desiresContent ? "▼ " : "► ";
}
return r;
},
},
};
</script>
<style scoped>
@ -45,6 +46,8 @@ export default {
cursor: pointer;
}
@media print {
.title { display: none; }
.title {
display: none;
}
}
</style>

View file

@ -1,22 +1,39 @@
<template>
<span :class="classes" class="message">
<vue3-markdown-it :source="content" v-bind="$mdOpts"></vue3-markdown-it>
<div class="reactions">
<div class="message-outer">
<div class="message-data" v-if="show_message_data">
<div class="from">{{ message.sender_full_name }}</div>
<div class="time">{{ time }}</div>
</div>
<div :class="classes" class="message">
<vue3-markdown-it :source="content" v-bind="$mdOpts"></vue3-markdown-it>
</div>
<div class="message-data-reactions" v-if="show_message_data">
<span
class="reaction"
v-for="reaction in message.reactions"
:key="reaction"
>
{{ String.fromCodePoint("0x" + reaction.emoji_code) }}
</span>
</div>
<div class="reactions ui">
<template v-for="reaction in reactions" :key="reaction">
{{ reaction }}
</template>
</div>
</span>
</div>
</template>
<script>
import emoji from "../../mixins/emoji";
var EmojiConvertor = require("emoji-js");
var emojiConv = new EmojiConvertor();
/*eslint no-unused-vars: "off"*/
/*eslint no-undef: "off"*/
export default {
name: "Message",
props: ["message"],
props: ["message", "show_message_data"],
mixins: [emoji],
computed: {
rawJSON() {
return "```json\n" + JSON.stringify(this.message, null, 2) + "\n```";
@ -27,15 +44,15 @@ export default {
c = c.replaceAll('src="', 'src="' + url);
c = c.replaceAll('href="/', 'href="' + url + "/");
const referrers = this.$store.state
.topics.find(t => t.title == this.message.subject)
.messages.filter(
(m) =>
m.responseTo &&
m.responseTo.id == this.message.id &&
m.responseTo.sender_id == this.message.sender_id &&
this.message.content.includes(m.responseTo.quote)
);
const referrers = this.$store.state.topics
.find((t) => t.title == this.message.subject)
.messages.filter(
(m) =>
m.responseTo &&
m.responseTo.id == this.message.id &&
m.responseTo.sender_id == this.message.sender_id &&
this.message.content.includes(m.responseTo.quote)
);
referrers.forEach((m) => {
const classes = m.reactions.map((r) => "u" + r.emoji_code).join(" ");
c = c.replace(
@ -58,6 +75,12 @@ export default {
classes() {
return this.message.reactions.map((r) => "u" + r.emoji_code);
},
time() {
var ts = this.message.timestamp;
var ts_ms = ts * 1000;
var date_ob = new Date(ts_ms);
return date_ob.toLocaleString();
},
},
created() {
// console.log(this.message.content);
@ -82,6 +105,7 @@ export default {
justify-content: center;
background-color: rgba(255, 255, 255, 0.5);
font-size: 3rem;
pointer-events: none;
}
.reactions,
.reactions::before,
@ -89,4 +113,19 @@ export default {
all: revert;
display: none;
}
.message-data {
display: flex;
border-bottom: 1px solid #666;
}
.message-data > div {
flex-grow: 1;
}
.message-data .from:after {
content: ":";
}
.message-data .time {
text-align: right;
}
</style>

View file

@ -1,17 +1,19 @@
<template>
<section :class="['content', currentStream]">
<h1 class="title"> {{ currentStream.replace('pub-', '') }} </h1>
<h1 class="title">{{ currentStream.replace("pub-", "") }}</h1>
<Chapter
v-for="topic in sortedTopics"
:key="topic.title"
:topic="topic"
:print="print"
:show_message_data="show_message_data"
/>
</section>
</template>
<script>
import { mapGetters, mapState } from "vuex";
import Chapter from './Chapter.vue';
import Chapter from "./Chapter.vue";
export default {
name: "Content",
@ -23,6 +25,7 @@ export default {
...mapGetters(["sortedTopics"]),
},
methods: {},
props: ["print", "show_message_data"],
};
</script>

View file

@ -1,29 +1,31 @@
<script>
import { mapState } from 'vuex';
import { mapState } from "vuex";
import emoji from "../../mixins/emoji";
export default {
name: "Styles",
mixins: [emoji],
computed: {
...mapState([
'rules'
]),
...mapState(["rules"]),
},
data() {
return {
el: null,
}
};
},
methods: {
generateStyleRules() {
let styles = "";
this.rules.map((r) => {
styles += `.${r.parentClassName} ${r.className}`
if (this.containsEmoji(r.className)) {
styles += `, .${r.parentClassName} .u${this.toEmojiCode(r.className)}`
if (r.className.startsWith("@")) {
styles += r.className;
} else {
styles += `.${r.parentClassName} ${r.className}`;
if (this.containsEmoji(r.className)) {
styles += `, .${r.parentClassName} .u${this.toEmojiCode(
r.className
)}`;
}
}
styles += "{";
r.rules.map((s) => {
@ -40,15 +42,15 @@ export default {
},
},
mounted() {
this.el = this.createStyleElement()
document.head.appendChild(this.el)
this.el = this.createStyleElement();
document.head.appendChild(this.el);
},
watch: {
rules() {
console.log('rules!')
const newStyle = this.createStyleElement()
document.head.replaceChild(newStyle, this.el)
this.el = newStyle
console.log("rules!");
const newStyle = this.createStyleElement();
document.head.replaceChild(newStyle, this.el);
this.el = newStyle;
},
},
};

View file

@ -18,7 +18,7 @@
export default {
methods: {
toEmojiCode: (emoji) => {
console.log(emoji);
// console.log(emoji);
return emoji.replace(/\p{Emoji}/gu, (m) => m.codePointAt(0).toString(16));
},

View file

@ -4,13 +4,22 @@
{{ show_ui ? "Hide" : "Show" }} UI
</button>
<splitpanes class="default-theme">
<pane v-if="show_ui" size="10" min-size="5">
<pane v-if="show_ui" size="10" min-size="5" @resize="resizer">
<Streams />
<button @click="toggle_ui">{{ show_ui ? "Hide" : "Show" }} UI</button>
<button @click="print">Print</button>
<div class="controls">
<button @click="toggle_ui">{{ show_ui ? "Hide" : "Show" }} UI</button>
<button @click="print">Print</button>
<input
type="checkbox"
id="msg-data"
value="1"
v-model="show_message_data"
/>
<label for="msg-data">Show chat message data</label>
</div>
</pane>
<pane size="55">
<Content />
<Content :print="!show_ui" :show_message_data="show_message_data" />
</pane>
<pane v-if="show_ui" size="35" min-size="15">
<Rules />
@ -41,6 +50,8 @@ export default {
data: () => {
return {
show_ui: true,
show_message_data: false,
panel_sizes: { 0: 10, 1: 55, 2: 35 },
};
},
computed: {
@ -49,12 +60,15 @@ export default {
},
},
methods: {
resizer(e, i) {
console.log(e, i);
},
print() {
// let prev = this.show_ui;
this.toggle_ui(null, false);
setTimeout(() => {
window.print();
if (prev) this.toggle_ui(null, true);
// if (prev) this.toggle_ui(null, true);
}, 1000);
let paged = new Previewer();
console.log(paged);
@ -90,6 +104,11 @@ export default {
height: 100vh;
}
.controls {
display: flex;
flex-direction: column;
}
.print .pane-wrapper {
height: auto;
}
@ -98,10 +117,25 @@ export default {
overflow: initial;
}
iframe {
.print .content iframe {
width: 100%;
height: 100%;
}
/* absolutely needed to make the page breaks work (next style) */
.print section {
display: block !important;
}
.print .body {
page-break-after: always;
border-bottom: 3px dotted green;
}
.print .body:first-of-type {
page-break-after: always;
border-bottom: 3px dotted yellow;
}
.float-btn {
position: fixed;
z-index: 1000;
@ -109,7 +143,7 @@ iframe {
@media print {
.ui {
display: none;
display: none !important;
}
}
</style>