From c2ac53c66b5cade26afd5622ad800bec7edffa92 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 21:47:30 -0700 Subject: [PATCH 1/8] mkv13 media list --- .../client/src/components/MkMediaList.vue | 238 +++++++++--------- 1 file changed, 115 insertions(+), 123 deletions(-) diff --git a/packages/client/src/components/MkMediaList.vue b/packages/client/src/components/MkMediaList.vue index 8b6d2c2c95..9a1d1f1704 100644 --- a/packages/client/src/components/MkMediaList.vue +++ b/packages/client/src/components/MkMediaList.vue @@ -1,19 +1,19 @@ <template> -<div class="hoawjimk"> - <XBanner v-for="media in mediaList.filter(media => !previewable(media))" :key="media.id" :media="media"/> - <div v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container" :class="{ dmWidth: inDm }"> - <div ref="gallery" :data-count="mediaList.filter(media => previewable(media)).length" @click.stop> - <template v-for="media in mediaList.filter(media => previewable(media))"> - <XVideo v-if="media.type.startsWith('video')" :key="media.id" :video="media"/> - <XImage v-else-if="media.type.startsWith('image')" :key="media.id" class="image" :data-id="media.id" :image="media" :raw="raw"/> - </template> + <div> + <XBanner v-for="media in mediaList.filter(media => !previewable(media))" :key="media.id" :media="media"/> + <div v-if="mediaList.filter(media => previewable(media)).length > 0" :class="$style.container, { dmWidth: inDm }"> + <div ref="gallery" :class="[$style.medias, count <= 4 ? $style['n' + count] : $style.nMany]"> + <template v-for="media in mediaList.filter(media => previewable(media))"> + <XVideo v-if="media.type.startsWith('video')" :key="media.id" :class="$style.media" :video="media"/> + <XImage v-else-if="media.type.startsWith('image')" :key="media.id" :class="$style.media" class="image" :data-id="media.id" :image="media" :raw="raw"/> + </template> + </div> </div> </div> -</div> </template> <script lang="ts" setup> -import { onMounted, ref } from 'vue'; +import { onMounted, ref, useCssModule } from 'vue'; import * as misskey from 'calckey-js'; import PhotoSwipeLightbox from 'photoswipe/lightbox'; import PhotoSwipe from 'photoswipe'; @@ -23,7 +23,6 @@ import XImage from '@/components/MkMediaImage.vue'; import XVideo from '@/components/MkMediaVideo.vue'; import * as os from '@/os'; import { FILE_TYPE_BROWSERSAFE } from '@/const'; -import { defaultStore } from '@/store'; const props = defineProps<{ mediaList: misskey.entities.DriveFile[]; @@ -31,8 +30,12 @@ const props = defineProps<{ inDm?: boolean; }>(); +const $style = useCssModule(); + const gallery = ref(null); const pswpZIndex = os.claimZIndex('middle'); +document.documentElement.style.setProperty('--mk-pswp-root-z-index', pswpZIndex.toString()); +const count = $computed(() => props.mediaList.filter(media => previewable(media)).length); onMounted(() => { const lightbox = new PhotoSwipeLightbox({ @@ -46,7 +49,8 @@ onMounted(() => { src: media.url, w: media.properties.width, h: media.properties.height, - alt: media.comment, + alt: media.comment ?? media.name, + comment: media.comment ?? media.name, }; if (media.properties.orientation != null && media.properties.orientation >= 5) { [item.w, item.h] = [item.h, item.w]; @@ -54,22 +58,24 @@ onMounted(() => { return item; }), gallery: gallery.value, + mainClass: $style.pswp, children: '.image', thumbSelector: '.image', loop: false, padding: window.innerWidth > 500 ? { top: 32, - bottom: 32, + bottom: 90, left: 32, right: 32, } : { top: 0, - bottom: 0, + bottom: 78, left: 0, right: 0, }, imageClickAction: 'close', tapAction: 'toggle-controls', + bgOpacity: 1, pswpModule: PhotoSwipe, }); @@ -81,6 +87,7 @@ onMounted(() => { const id = element.dataset.id; const file = props.mediaList.find(media => media.id === id); + if (!file) return; itemData.src = file.url; itemData.w = Number(file.properties.width); @@ -89,7 +96,8 @@ onMounted(() => { [itemData.w, itemData.h] = [itemData.h, itemData.w]; } itemData.msrc = file.thumbnailUrl; - itemData.alt = file.comment; + itemData.alt = file.comment ?? file.name; + itemData.comment = file.comment ?? file.name; itemData.thumbCropped = true; }); @@ -100,28 +108,34 @@ onMounted(() => { appendTo: 'wrapper', onInit: (el, pwsp) => { let textBox = document.createElement('p'); - textBox.className = 'pwsp__alt-text'; + textBox.className = 'pwsp__alt-text _acrylic'; 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.alt?.trim(); + pwsp.on('change', (a) => { + textBox.textContent = pwsp.currSlide.data.comment; }); }, }); }); lightbox.init(); + + window.addEventListener('popstate', () => { + if (lightbox.pswp && lightbox.pswp.isOpen === true) { + lightbox.pswp.close(); + return; + } + }); + + lightbox.on('beforeOpen', () => { + history.pushState(null, '', '#pswp'); + }); + + lightbox.on('close', () => { + if (window.location.hash === '#pswp') { + history.back(); + } + }); }); const previewable = (file: misskey.entities.DriveFile): boolean => { @@ -131,128 +145,106 @@ const previewable = (file: misskey.entities.DriveFile): boolean => { }; </script> -<style lang="scss" scoped> -.hoawjimk { +<style lang="scss" module> +.dmWidth { + min-width: 20rem; + max-width: 40rem; +} - > .dmWidth { - min-width: 20rem; - max-width: 40rem; +.container { + position: relative; + width: 100%; + margin-top: 4px; +} + +.medias { + display: grid; + grid-gap: 8px; + + // for webkit + height: 100%; + + &.n1 { + aspect-ratio: 16/9; + grid-template-rows: 1fr; } - > .gird-container { - position: relative; - width: 100%; - margin-top: 4px; - border-radius: var(--radius); - overflow: hidden; + &.n2 { + aspect-ratio: 16/9; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr; + } - &:before { - content: ''; - display: block; - padding-top: 56.25% // 16:9; + &.n3 { + aspect-ratio: 16/9; + grid-template-columns: 1fr 0.5fr; + grid-template-rows: 1fr 1fr; + + > .media:nth-child(1) { + grid-row: 1 / 3; } - > div { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - display: grid; - grid-gap: 8px; - - > * { - overflow: hidden; - border-radius: 6px; - } - - &[data-count="1"] { - grid-template-rows: 1fr; - } - - &[data-count="2"] { - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr; - } - - &[data-count="3"] { - grid-template-columns: 1fr 0.5fr; - grid-template-rows: 1fr 1fr; - - > *:nth-child(1) { - grid-row: 1 / 3; - } - - > *:nth-child(3) { - grid-column: 2 / 3; - grid-row: 2 / 3; - } - } - - &[data-count="4"] { - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr 1fr; - } - - > *:nth-child(1) { - grid-column: 1 / 2; - grid-row: 1 / 2; - } - - > *:nth-child(2) { - grid-column: 2 / 3; - grid-row: 1 / 2; - } - - > *:nth-child(3) { - grid-column: 1 / 2; - grid-row: 2 / 3; - } - - > *:nth-child(4) { - grid-column: 2 / 3; - grid-row: 2 / 3; - } + > .media:nth-child(3) { + grid-column: 2 / 3; + grid-row: 2 / 3; } } + + &.n4 { + aspect-ratio: 16/9; + grid-template-columns: 1fr 1fr; + grid-template-rows: 1fr 1fr; + } + + &.nMany { + grid-template-columns: 1fr 1fr; + + > .media { + aspect-ratio: 16/9; + } + } +} + +.media { + overflow: hidden; // clipにするとバグる + border-radius: 8px; +} + +.pswp { + --pswp-root-z-index: var(--mk-pswp-root-z-index, 2000700) !important; + --pswp-bg: var(--modalBg) !important; } </style> <style lang="scss"> -.pswp { - // なぜか機能しない - //z-index: v-bind(pswpZIndex); - z-index: 2000000; +.pswp__bg { + background: var(--modalBg); + backdrop-filter: var(--modalBgFilter); } + .pwsp__alt-text-container { display: flex; flex-direction: row; align-items: center; position: absolute; - bottom: 30px; + bottom: 20px; left: 50%; transform: translateX(-50%); width: 75%; + max-width: 800px; } .pwsp__alt-text { - color: white; + color: var(--fg); margin: 0 auto; text-align: center; - padding: 10px; - background: rgba(0, 0, 0, 0.5); - border-radius: 5px; - - max-height: 10vh; - overflow-x: clip; + padding: var(--margin); + border-radius: var(--radius); + max-height: 8em; overflow-y: auto; - overscroll-behavior: contain; + text-shadow: var(--bg) 0 0 10px, var(--bg) 0 0 3px, var(--bg) 0 0 3px; + white-space: pre-line; } - -.pwsp__alt-text:empty { - display: none; -} - </style> From 89a010db1b3bfd27cd1ebdaa65424b451252f600 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 21:47:38 -0700 Subject: [PATCH 2/8] dev27 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 938afafbcd..bffbba6269 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calckey", - "version": "13.2.0-dev26", + "version": "13.2.0-dev27", "codename": "aqua", "repository": { "type": "git", From 3b5b90879cd32cbe558e376adbff3a751247d99f Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 21:53:17 -0700 Subject: [PATCH 3/8] dont change state --- packages/client/src/components/MkMediaList.vue | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/client/src/components/MkMediaList.vue b/packages/client/src/components/MkMediaList.vue index 9a1d1f1704..6dd0dea274 100644 --- a/packages/client/src/components/MkMediaList.vue +++ b/packages/client/src/components/MkMediaList.vue @@ -126,16 +126,6 @@ onMounted(() => { return; } }); - - lightbox.on('beforeOpen', () => { - history.pushState(null, '', '#pswp'); - }); - - lightbox.on('close', () => { - if (window.location.hash === '#pswp') { - history.back(); - } - }); }); const previewable = (file: misskey.entities.DriveFile): boolean => { From c88627fc8875a5d68bc913234307e4eacbd3ba07 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 21:59:11 -0700 Subject: [PATCH 4/8] back button in settings --- packages/client/src/components/global/MkPageHeader.vue | 2 ++ packages/client/src/pages/settings/index.vue | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/client/src/components/global/MkPageHeader.vue b/packages/client/src/components/global/MkPageHeader.vue index a6f71d9674..8293f10e28 100644 --- a/packages/client/src/components/global/MkPageHeader.vue +++ b/packages/client/src/components/global/MkPageHeader.vue @@ -1,6 +1,7 @@ <template> <div v-if="show" ref="el" class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick"> <div v-if="narrow" class="buttons left" @click="openAccountMenu"> + <i @click="history.back()" v-if="props.displayBackButton" class="icon ph-caret-left ph-bold ph-lg"></i> <MkAvatar v-if="props.displayMyAvatar && $i" class="avatar" :user="$i" :disable-preview="true"/> </div> <template v-if="metadata"> @@ -59,6 +60,7 @@ const props = defineProps<{ }[]; thin?: boolean; displayMyAvatar?: boolean; + displayBackButton?: boolean; }>(); const emit = defineEmits<{ diff --git a/packages/client/src/pages/settings/index.vue b/packages/client/src/pages/settings/index.vue index ef9ae91b92..b672b7011b 100644 --- a/packages/client/src/pages/settings/index.vue +++ b/packages/client/src/pages/settings/index.vue @@ -1,6 +1,6 @@ <template> <MkStickyContainer> - <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> + <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs" :display-back-button="true"/></template> <MkSpacer :content-max="900" :margin-min="20" :margin-max="32"> <div ref="el" class="vvcocwet" :class="{ wide: !narrow }"> <div class="body"> From 9879bbe38ec7f278d0421d2f756398e1020773cc Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 21:59:35 -0700 Subject: [PATCH 5/8] display back button in note --- packages/client/src/pages/note.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/pages/note.vue b/packages/client/src/pages/note.vue index 5298194a6d..cff6b252b5 100644 --- a/packages/client/src/pages/note.vue +++ b/packages/client/src/pages/note.vue @@ -1,6 +1,6 @@ <template> <MkStickyContainer> - <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> + <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs" :display-back-button="true"/></template> <MkSpacer :content-max="800" :marginMin="6"> <div class="fcuexfpr"> <transition :name="$store.state.animation ? 'fade' : ''" mode="out-in"> From bcd5779a9ddb98f02a873a09718a639522262374 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 22:03:24 -0700 Subject: [PATCH 6/8] fix --- packages/client/src/components/global/MkPageHeader.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/components/global/MkPageHeader.vue b/packages/client/src/components/global/MkPageHeader.vue index 8293f10e28..1b6b197a86 100644 --- a/packages/client/src/components/global/MkPageHeader.vue +++ b/packages/client/src/components/global/MkPageHeader.vue @@ -1,9 +1,9 @@ <template> <div v-if="show" ref="el" class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick"> - <div v-if="narrow" class="buttons left" @click="openAccountMenu"> <i @click="history.back()" v-if="props.displayBackButton" class="icon ph-caret-left ph-bold ph-lg"></i> - <MkAvatar v-if="props.displayMyAvatar && $i" class="avatar" :user="$i" :disable-preview="true"/> - </div> + <div v-if="narrow" class="buttons left" @click="openAccountMenu"> + <MkAvatar v-if="props.displayMyAvatar && $i" class="avatar" :user="$i" :disable-preview="true"/> + </div> <template v-if="metadata"> <div v-if="!hideTitle" class="titleContainer" @click="showTabsPopup"> <MkAvatar v-if="metadata.avatar" class="avatar" :user="metadata.avatar" :disable-preview="true" :show-indicator="true"/> From b6e3dada807e502ddd442d11a2f371cb3fe13b75 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 22:03:38 -0700 Subject: [PATCH 7/8] dev28 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bffbba6269..41793af474 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calckey", - "version": "13.2.0-dev27", + "version": "13.2.0-dev28", "codename": "aqua", "repository": { "type": "git", From 3f48a9926b26f58a94767b5c5729b74c8d7227d7 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Tue, 4 Apr 2023 22:12:55 -0700 Subject: [PATCH 8/8] more fix --- package.json | 2 +- packages/client/src/components/global/MkPageHeader.vue | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 41793af474..bb544b62b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calckey", - "version": "13.2.0-dev28", + "version": "13.2.0-dev29", "codename": "aqua", "repository": { "type": "git", diff --git a/packages/client/src/components/global/MkPageHeader.vue b/packages/client/src/components/global/MkPageHeader.vue index 1b6b197a86..01f6aa35da 100644 --- a/packages/client/src/components/global/MkPageHeader.vue +++ b/packages/client/src/components/global/MkPageHeader.vue @@ -1,6 +1,6 @@ <template> <div v-if="show" ref="el" class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick"> - <i @click="history.back()" v-if="props.displayBackButton" class="icon ph-caret-left ph-bold ph-lg"></i> + <i @click="window.history.back()" v-if="props.displayBackButton" v-tooltip.noDelay="i18n.ts.goBack" class="icon backButton ph-caret-left ph-bold ph-lg"></i> <div v-if="narrow" class="buttons left" @click="openAccountMenu"> <MkAvatar v-if="props.displayMyAvatar && $i" class="avatar" :user="$i" :disable-preview="true"/> </div> @@ -296,6 +296,13 @@ onUnmounted(() => { } } + > .backButton { + display: flex; + align-items: center; + justify-content: center; + margin-left: 1rem; + } + > .titleContainer { display: flex; align-items: center;