From e9ab42c10afb4e27516c2d2b5e3e06630efe9edd Mon Sep 17 00:00:00 2001 From: Kayden Tebau Date: Wed, 28 Sep 2022 21:21:07 -0700 Subject: [PATCH 1/4] Alt text in image viewer --- .../client/src/components/media-image.vue | 2 +- packages/client/src/components/media-list.vue | 64 ++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/packages/client/src/components/media-image.vue b/packages/client/src/components/media-image.vue index ac22557f9..69b94514a 100644 --- a/packages/client/src/components/media-image.vue +++ b/packages/client/src/components/media-image.vue @@ -13,7 +13,7 @@ :href="image.url" :title="image.name" > - +
GIF
diff --git a/packages/client/src/components/media-list.vue b/packages/client/src/components/media-list.vue index 640f0defd..f9f017cfd 100644 --- a/packages/client/src/components/media-list.vue +++ b/packages/client/src/components/media-list.vue @@ -43,7 +43,8 @@ onMounted(() => { src: media.url, w: media.properties.width, h: media.properties.height, - alt: media.name, + alt: media.comment || media.name, + comment: media.comment, }; if (media.properties.orientation != null && media.properties.orientation >= 5) { [item.w, item.h] = [item.h, item.w]; @@ -86,9 +87,39 @@ onMounted(() => { [itemData.w, itemData.h] = [itemData.h, itemData.w]; } itemData.msrc = file.thumbnailUrl; + itemData.alt = file.comment || file.name; + itemData.comment = file.comment; itemData.thumbCropped = true; }); + lightbox.on('uiRegister', () => { + lightbox.pswp.ui.registerElement({ + name: 'altText', + className: 'pwsp__alt-text-container', + appendTo: 'wrapper', + onInit: (el, pwsp) => { + let textBox = document.createElement('p'); + textBox.className = 'pwsp__alt-text'; + el.appendChild(textBox); + + let preventProp = function(ev: Event): void { + ev.stopPropagation(); + }; + + // Allow scrolling/text selection + el.onwheel = preventProp; + el.onclick = preventProp; + el.onpointerdown = preventProp; + el.onpointercancel = preventProp; + el.onpointermove = preventProp; + + pwsp.on('change', () => { + textBox.textContent = pwsp.currSlide.data.comment?.trim(); + }); + }, + }); + }); + lightbox.init(); }); @@ -183,4 +214,35 @@ const previewable = (file: foundkey.entities.DriveFile): boolean => { // なぜか機能しない z-index: 2000000; } +.pwsp__alt-text-container { + display: flex; + flex-direction: row; + align-items: center; + + position: absolute; + bottom: 30px; + left: 50%; + transform: translateX(-50%); + + width: 75%; +} + +.pwsp__alt-text { + color: white; + margin: 0 auto; + text-align: center; + padding: 10px; + background: rgba(0, 0, 0, 0.5); + border-radius: 5px; + + max-height: 10vh; + overflow-x: clip; + overflow-y: auto; + overscroll-behavior: contain; +} + +.pwsp__alt-text:empty { + display: none; +} + From 41e7af1662bdeebbf72466f48e30bbdec5e509ac Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sat, 1 Oct 2022 13:24:44 +0200 Subject: [PATCH 2/4] client refactor: merge script/i18n.ts into i18n.ts The file i18n.ts was basically only a few lines that call into scripts/i18n.ts. Instead of having the extra file it is just as good to have the relevant code for i18n in one file. Since i18n.ts is imported in many client components, while scripts/i18n.ts was only imported in i18n.ts, the latter seems better to keep. Added some more comments and translated the Japanese comments to English. --- packages/client/src/i18n.ts | 40 ++++++++++++++++++++++++++++- packages/client/src/scripts/i18n.ts | 29 --------------------- 2 files changed, 39 insertions(+), 30 deletions(-) delete mode 100644 packages/client/src/scripts/i18n.ts diff --git a/packages/client/src/i18n.ts b/packages/client/src/i18n.ts index 31e066960..b50cd7290 100644 --- a/packages/client/src/i18n.ts +++ b/packages/client/src/i18n.ts @@ -1,5 +1,43 @@ import { markRaw } from 'vue'; import { locale } from '@/config'; -import { I18n } from '@/scripts/i18n'; + +class I18n> { + // This contains all defined keys, even if a string is missing in a particular language. + // This is achieved by setting English strings as a fallback during locale generation in /locales/index.js + public ts: T; + + constructor(locale: T) { + this.ts = locale; + this.t = this.t.bind(this); + } + + // The key is a string (rather than a Symbol) to allow for the dot-delimited names. + // + // If possible it should probably be preferred to use the locale directly (i.e. the ts member), + // because it may allow for vue to cache information. + // + // Performs string interpolation for patters like `{foo}` and replaces it with the respective value from `args` (using its `toString()` method). + // If a pattern is present in the string but not provided in args, it will not be replaced. + // If `args` is not provided, no interpolation is performed. + public t(key: string, args?: Record): string { + try { + // Resolve dot-delimited names as properties of objects. + let str = key.split('.').reduce((o, i) => o[i], this.ts) as unknown as string; + + // Perform string interpolation. + if (args) { + for (const [k, v] of Object.entries(args)) { + str = str.replace(`{${k}}`, v.toString()); + } + } + + return str; + } catch (err) { + // This should normally not happen because of the English language fallback strings, see comment for ts member. + console.warn(`missing localization '${key}'`); + return key; + } + } +} export const i18n = markRaw(new I18n(locale)); diff --git a/packages/client/src/scripts/i18n.ts b/packages/client/src/scripts/i18n.ts deleted file mode 100644 index 54184386d..000000000 --- a/packages/client/src/scripts/i18n.ts +++ /dev/null @@ -1,29 +0,0 @@ -export class I18n> { - public ts: T; - - constructor(locale: T) { - this.ts = locale; - - //#region BIND - this.t = this.t.bind(this); - //#endregion - } - - // string にしているのは、ドット区切りでのパス指定を許可するため - // なるべくこのメソッド使うよりもlocale直接参照の方がvueのキャッシュ効いてパフォーマンスが良いかも - public t(key: string, args?: Record): string { - try { - let str = key.split('.').reduce((o, i) => o[i], this.ts) as unknown as string; - - if (args) { - for (const [k, v] of Object.entries(args)) { - str = str.replace(`{${k}}`, v.toString()); - } - } - return str; - } catch (err) { - console.warn(`missing localization '${key}'`); - return key; - } - } -} From b9f20ca16d05472f556425a740e598308a4b775b Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sat, 1 Oct 2022 13:41:59 +0200 Subject: [PATCH 3/4] client: prefer absolute over relative imports --- packages/client/src/account.ts | 4 ++-- packages/client/src/components/signin.vue | 2 +- packages/client/src/directives/hotkey.ts | 2 +- packages/client/src/instance.ts | 2 +- packages/client/src/menu.ts | 2 +- packages/client/src/pizzax.ts | 6 +++--- packages/client/src/scripts/emojilist.ts | 2 +- packages/client/src/store.ts | 4 ++-- packages/client/src/theme-store.ts | 2 +- packages/client/src/ui/deck/deck-store.ts | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/client/src/account.ts b/packages/client/src/account.ts index 718c7b5b0..c10dcfb06 100644 --- a/packages/client/src/account.ts +++ b/packages/client/src/account.ts @@ -1,7 +1,7 @@ import { defineAsyncComponent, reactive } from 'vue'; import * as foundkey from 'foundkey-js'; -import { showSuspendedDialog } from './scripts/show-suspended-dialog'; -import { i18n } from './i18n'; +import { showSuspendedDialog } from '@/scripts/show-suspended-dialog'; +import { i18n } from '@/i18n'; import { del, get, set } from '@/scripts/idb-proxy'; import { apiUrl } from '@/config'; import { waiting, api, popup, popupMenu, success, alert } from '@/os'; diff --git a/packages/client/src/components/signin.vue b/packages/client/src/components/signin.vue index f4e32fc7e..6fb37f4fd 100644 --- a/packages/client/src/components/signin.vue +++ b/packages/client/src/components/signin.vue @@ -51,7 +51,7 @@