fix: improve chat log rendering (#4686)
This commit is contained in:
parent
a3fc57bfb7
commit
3ad1daaf8c
11
.pnp.cjs
generated
11
.pnp.cjs
generated
|
@ -47,6 +47,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["@percy/cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.1.2"],\
|
||||
["@popperjs/core", "npm:2.11.6"],\
|
||||
["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.2"],\
|
||||
["@twuni/emojify", "npm:1.0.2"],\
|
||||
["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.1.2"],\
|
||||
["@vue/test-utils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.1.0"],\
|
||||
["bootstrap", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.2.2"],\
|
||||
|
@ -2226,6 +2227,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@twuni/emojify", [\
|
||||
["npm:1.0.2", {\
|
||||
"packageLocation": "./.yarn/cache/@twuni-emojify-npm-1.0.2-a45d6eb0a7-0044c83b05.zip/node_modules/@twuni/emojify/",\
|
||||
"packageDependencies": [\
|
||||
["@twuni/emojify", "npm:1.0.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@types/estree", [\
|
||||
["npm:1.0.0", {\
|
||||
"packageLocation": "./.yarn/cache/@types-estree-npm-1.0.0-eddde5b631-910d97fb70.zip/node_modules/@types/estree/",\
|
||||
|
@ -8580,6 +8590,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["@percy/cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.1.2"],\
|
||||
["@popperjs/core", "npm:2.11.6"],\
|
||||
["@rollup/pluginutils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.0.2"],\
|
||||
["@twuni/emojify", "npm:1.0.2"],\
|
||||
["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.1.2"],\
|
||||
["@vue/test-utils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.1.0"],\
|
||||
["bootstrap", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.2.2"],\
|
||||
|
|
BIN
.yarn/cache/@twuni-emojify-npm-1.0.2-a45d6eb0a7-0044c83b05.zip
vendored
Normal file
BIN
.yarn/cache/@twuni-emojify-npm-1.0.2-a45d6eb0a7-0044c83b05.zip
vendored
Normal file
Binary file not shown.
|
@ -22,6 +22,8 @@
|
|||
<script setup>
|
||||
import { onMounted, reactive } from 'vue'
|
||||
import { DateTime } from 'luxon'
|
||||
import { emojify } from '@twuni/emojify'
|
||||
import uniq from 'lodash-es/uniq'
|
||||
import {
|
||||
NTimeline,
|
||||
NTimelineItem
|
||||
|
@ -61,9 +63,12 @@ const colors = [
|
|||
|
||||
onMounted(() => {
|
||||
const authorColors = {}
|
||||
|
||||
// Get chat log data from embedded json tag
|
||||
const chatLog = JSON.parse(document.getElementById(`${props.componentId}-data`).textContent || '[]')
|
||||
if (chatLog.length > 0) {
|
||||
const authorNames = uniq(chatLog.map(l => l.author))
|
||||
|
||||
let idx = 1
|
||||
let colorIdx = 0
|
||||
for (const logItem of chatLog) {
|
||||
|
@ -75,12 +80,22 @@ onMounted(() => {
|
|||
colorIdx = 0
|
||||
}
|
||||
}
|
||||
|
||||
// -> Format text
|
||||
let txt = emojify(logItem.text)
|
||||
if (txt.indexOf('@') >= 0) {
|
||||
for (const authorName of authorNames) {
|
||||
txt = txt.replaceAll(`@${authorName}`, `<span class="user-mention">${authorName}</span>`)
|
||||
}
|
||||
}
|
||||
txt = txt.replaceAll('href="/user_uploads/', 'href="https://zulip.ietf.org/user_uploads/')
|
||||
|
||||
// -> Generate log item
|
||||
state.items.push({
|
||||
id: `logitem-${idx}`,
|
||||
color: authorColors[logItem.author],
|
||||
author: logItem.author,
|
||||
text: logItem.text,
|
||||
text: txt,
|
||||
time: DateTime.fromISO(logItem.time).toFormat('dd LLLL yyyy \'at\' HH:mm:ss a ZZZZ')
|
||||
})
|
||||
idx++
|
||||
|
@ -90,9 +105,58 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../shared/colors.scss';
|
||||
|
||||
.chatlog {
|
||||
.n-timeline-item-content__content > div > p {
|
||||
.n-timeline-item-content__content {
|
||||
> div > p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background-color: $gray-100;
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
margin-top: -8px;
|
||||
|
||||
> p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.message_inline_image {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Manual user mention
|
||||
.user-mention {
|
||||
display: inline-block;
|
||||
padding: 1px 5px;
|
||||
background-color: rgba($purple, .05);
|
||||
color: $purple;
|
||||
font-weight: 500;
|
||||
border-radius: 4px;
|
||||
|
||||
> .user-mention {
|
||||
padding: 0;
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '@';
|
||||
}
|
||||
}
|
||||
|
||||
// User reply mention
|
||||
.user-mention + a {
|
||||
text-decoration: none;
|
||||
color: $purple;
|
||||
font-style: italic;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
139
client/shared/colors.scss
Normal file
139
client/shared/colors.scss
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Bootstrap 5 Color Variables
|
||||
// Extracted from https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss
|
||||
// Copyright (c) 2011-2022 Twitter, Inc.
|
||||
// Copyright (c) 2011-2022 The Bootstrap Authors
|
||||
|
||||
// Tint a color: mix a color with white
|
||||
@function tint-color($color, $weight) {
|
||||
@return mix(white, $color, $weight);
|
||||
}
|
||||
|
||||
// Shade a color: mix a color with black
|
||||
@function shade-color($color, $weight) {
|
||||
@return mix(black, $color, $weight);
|
||||
}
|
||||
|
||||
// Color system
|
||||
|
||||
$white: #fff !default;
|
||||
$gray-100: #f8f9fa !default;
|
||||
$gray-200: #e9ecef !default;
|
||||
$gray-300: #dee2e6 !default;
|
||||
$gray-400: #ced4da !default;
|
||||
$gray-500: #adb5bd !default;
|
||||
$gray-600: #6c757d !default;
|
||||
$gray-700: #495057 !default;
|
||||
$gray-800: #343a40 !default;
|
||||
$gray-900: #212529 !default;
|
||||
$black: #000 !default;
|
||||
|
||||
$blue: #0d6efd !default;
|
||||
$indigo: #6610f2 !default;
|
||||
$purple: #6f42c1 !default;
|
||||
$pink: #d63384 !default;
|
||||
$red: #dc3545 !default;
|
||||
$orange: #fd7e14 !default;
|
||||
$yellow: #ffc107 !default;
|
||||
$green: #198754 !default;
|
||||
$teal: #20c997 !default;
|
||||
$cyan: #0dcaf0 !default;
|
||||
|
||||
$blue-100: tint-color($blue, 80%) !default;
|
||||
$blue-200: tint-color($blue, 60%) !default;
|
||||
$blue-300: tint-color($blue, 40%) !default;
|
||||
$blue-400: tint-color($blue, 20%) !default;
|
||||
$blue-500: $blue !default;
|
||||
$blue-600: shade-color($blue, 20%) !default;
|
||||
$blue-700: shade-color($blue, 40%) !default;
|
||||
$blue-800: shade-color($blue, 60%) !default;
|
||||
$blue-900: shade-color($blue, 80%) !default;
|
||||
|
||||
$indigo-100: tint-color($indigo, 80%) !default;
|
||||
$indigo-200: tint-color($indigo, 60%) !default;
|
||||
$indigo-300: tint-color($indigo, 40%) !default;
|
||||
$indigo-400: tint-color($indigo, 20%) !default;
|
||||
$indigo-500: $indigo !default;
|
||||
$indigo-600: shade-color($indigo, 20%) !default;
|
||||
$indigo-700: shade-color($indigo, 40%) !default;
|
||||
$indigo-800: shade-color($indigo, 60%) !default;
|
||||
$indigo-900: shade-color($indigo, 80%) !default;
|
||||
|
||||
$purple-100: tint-color($purple, 80%) !default;
|
||||
$purple-200: tint-color($purple, 60%) !default;
|
||||
$purple-300: tint-color($purple, 40%) !default;
|
||||
$purple-400: tint-color($purple, 20%) !default;
|
||||
$purple-500: $purple !default;
|
||||
$purple-600: shade-color($purple, 20%) !default;
|
||||
$purple-700: shade-color($purple, 40%) !default;
|
||||
$purple-800: shade-color($purple, 60%) !default;
|
||||
$purple-900: shade-color($purple, 80%) !default;
|
||||
|
||||
$pink-100: tint-color($pink, 80%) !default;
|
||||
$pink-200: tint-color($pink, 60%) !default;
|
||||
$pink-300: tint-color($pink, 40%) !default;
|
||||
$pink-400: tint-color($pink, 20%) !default;
|
||||
$pink-500: $pink !default;
|
||||
$pink-600: shade-color($pink, 20%) !default;
|
||||
$pink-700: shade-color($pink, 40%) !default;
|
||||
$pink-800: shade-color($pink, 60%) !default;
|
||||
$pink-900: shade-color($pink, 80%) !default;
|
||||
|
||||
$red-100: tint-color($red, 80%) !default;
|
||||
$red-200: tint-color($red, 60%) !default;
|
||||
$red-300: tint-color($red, 40%) !default;
|
||||
$red-400: tint-color($red, 20%) !default;
|
||||
$red-500: $red !default;
|
||||
$red-600: shade-color($red, 20%) !default;
|
||||
$red-700: shade-color($red, 40%) !default;
|
||||
$red-800: shade-color($red, 60%) !default;
|
||||
$red-900: shade-color($red, 80%) !default;
|
||||
|
||||
$orange-100: tint-color($orange, 80%) !default;
|
||||
$orange-200: tint-color($orange, 60%) !default;
|
||||
$orange-300: tint-color($orange, 40%) !default;
|
||||
$orange-400: tint-color($orange, 20%) !default;
|
||||
$orange-500: $orange !default;
|
||||
$orange-600: shade-color($orange, 20%) !default;
|
||||
$orange-700: shade-color($orange, 40%) !default;
|
||||
$orange-800: shade-color($orange, 60%) !default;
|
||||
$orange-900: shade-color($orange, 80%) !default;
|
||||
|
||||
$yellow-100: tint-color($yellow, 80%) !default;
|
||||
$yellow-200: tint-color($yellow, 60%) !default;
|
||||
$yellow-300: tint-color($yellow, 40%) !default;
|
||||
$yellow-400: tint-color($yellow, 20%) !default;
|
||||
$yellow-500: $yellow !default;
|
||||
$yellow-600: shade-color($yellow, 20%) !default;
|
||||
$yellow-700: shade-color($yellow, 40%) !default;
|
||||
$yellow-800: shade-color($yellow, 60%) !default;
|
||||
$yellow-900: shade-color($yellow, 80%) !default;
|
||||
|
||||
$green-100: tint-color($green, 80%) !default;
|
||||
$green-200: tint-color($green, 60%) !default;
|
||||
$green-300: tint-color($green, 40%) !default;
|
||||
$green-400: tint-color($green, 20%) !default;
|
||||
$green-500: $green !default;
|
||||
$green-600: shade-color($green, 20%) !default;
|
||||
$green-700: shade-color($green, 40%) !default;
|
||||
$green-800: shade-color($green, 60%) !default;
|
||||
$green-900: shade-color($green, 80%) !default;
|
||||
|
||||
$teal-100: tint-color($teal, 80%) !default;
|
||||
$teal-200: tint-color($teal, 60%) !default;
|
||||
$teal-300: tint-color($teal, 40%) !default;
|
||||
$teal-400: tint-color($teal, 20%) !default;
|
||||
$teal-500: $teal !default;
|
||||
$teal-600: shade-color($teal, 20%) !default;
|
||||
$teal-700: shade-color($teal, 40%) !default;
|
||||
$teal-800: shade-color($teal, 60%) !default;
|
||||
$teal-900: shade-color($teal, 80%) !default;
|
||||
|
||||
$cyan-100: tint-color($cyan, 80%) !default;
|
||||
$cyan-200: tint-color($cyan, 60%) !default;
|
||||
$cyan-300: tint-color($cyan, 40%) !default;
|
||||
$cyan-400: tint-color($cyan, 20%) !default;
|
||||
$cyan-500: $cyan !default;
|
||||
$cyan-600: shade-color($cyan, 20%) !default;
|
||||
$cyan-700: shade-color($cyan, 40%) !default;
|
||||
$cyan-800: shade-color($cyan, 60%) !default;
|
||||
$cyan-900: shade-color($cyan, 80%) !default;
|
|
@ -43,7 +43,6 @@ cat << EOF > "$EXCLUDE"
|
|||
*.doc
|
||||
*.exe
|
||||
*.html
|
||||
*.json
|
||||
*.mib
|
||||
*.new
|
||||
*.p7s
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"@fullcalendar/timegrid": "5.11.3",
|
||||
"@fullcalendar/vue3": "5.11.2",
|
||||
"@popperjs/core": "2.11.6",
|
||||
"@twuni/emojify": "1.0.2",
|
||||
"bootstrap": "5.2.2",
|
||||
"bootstrap-icons": "1.9.1",
|
||||
"browser-fs-access": "0.31.1",
|
||||
|
|
|
@ -1719,6 +1719,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@twuni/emojify@npm:1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "@twuni/emojify@npm:1.0.2"
|
||||
checksum: 0044c83b0589767dae1c1bb933cd56f2e5031a438f0fc993413e4cc229080e29c275cdd836be33ee02ddd59a5d1d6223a718685650f11ecfffc69c881c072152
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/estree@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@types/estree@npm:1.0.0"
|
||||
|
@ -7138,6 +7145,7 @@ browserlist@latest:
|
|||
"@percy/cypress": 3.1.2
|
||||
"@popperjs/core": 2.11.6
|
||||
"@rollup/pluginutils": 5.0.2
|
||||
"@twuni/emojify": 1.0.2
|
||||
"@vitejs/plugin-vue": 3.1.2
|
||||
"@vue/test-utils": 2.1.0
|
||||
bootstrap: 5.2.2
|
||||
|
|
Loading…
Reference in a new issue