fix: improve chat log rendering (#4686)

This commit is contained in:
Nicolas Giard 2022-11-06 07:31:13 -05:00 committed by GitHub
parent a3fc57bfb7
commit 3ad1daaf8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 226 additions and 4 deletions

11
.pnp.cjs generated
View file

@ -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"],\

Binary file not shown.

View file

@ -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 {
margin-bottom: 0;
.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
View 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;

View file

@ -43,7 +43,6 @@ cat << EOF > "$EXCLUDE"
*.doc
*.exe
*.html
*.json
*.mib
*.new
*.p7s

View file

@ -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",

View file

@ -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