mirror of
https://iceshrimp.dev/crimekillz/trashposs
synced 2024-11-24 01:39:06 +01:00
Allow enlarge user profile image as lightbox, initial work by Lhcfl
This commit is contained in:
parent
1d168e811a
commit
e318c48a5e
@ -15,6 +15,26 @@
|
|||||||
:user="user"
|
:user="user"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
<span
|
||||||
|
v-else-if="showLightBox"
|
||||||
|
v-user-preview="disablePreview ? undefined : user.id"
|
||||||
|
class="eiwwqkts _noSelect showLightBox"
|
||||||
|
:class="{
|
||||||
|
cat: user.isCat,
|
||||||
|
square: defaultStore.state.squareAvatars,
|
||||||
|
}"
|
||||||
|
:style="{ color }"
|
||||||
|
:title="acct(user)"
|
||||||
|
ref="gallery"
|
||||||
|
@click.stop
|
||||||
|
>
|
||||||
|
<img class="inner avatar" :src="url" decoding="async" />
|
||||||
|
<MkUserOnlineIndicator
|
||||||
|
v-if="showIndicator && user.instance == null"
|
||||||
|
class="indicator"
|
||||||
|
:user="user"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
<MkA
|
<MkA
|
||||||
v-else
|
v-else
|
||||||
v-user-preview="disablePreview ? undefined : user.id"
|
v-user-preview="disablePreview ? undefined : user.id"
|
||||||
@ -36,25 +56,30 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, watch } from "vue";
|
import { onMounted, ref, watch } from "vue";
|
||||||
import type * as misskey from "trashposs-js";
|
import type * as misskey from "trashposs-js";
|
||||||
import { getStaticImageUrl } from "@/scripts/get-static-image-url";
|
import { getStaticImageUrl } from "@/scripts/get-static-image-url";
|
||||||
import { extractAvgColorFromBlurhash } from "@/scripts/extract-avg-color-from-blurhash";
|
import { extractAvgColorFromBlurhash } from "@/scripts/extract-avg-color-from-blurhash";
|
||||||
import { acct, userPage } from "@/filters/user";
|
import { acct, userPage } from "@/filters/user";
|
||||||
import MkUserOnlineIndicator from "@/components/MkUserOnlineIndicator.vue";
|
import MkUserOnlineIndicator from "@/components/MkUserOnlineIndicator.vue";
|
||||||
import { defaultStore } from "@/store";
|
import { defaultStore } from "@/store";
|
||||||
|
import PhotoSwipeLightbox from "photoswipe/lightbox";
|
||||||
|
import PhotoSwipe from "photoswipe";
|
||||||
|
import "photoswipe/style.css";
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
user: misskey.entities.User;
|
user: misskey.entities.User;
|
||||||
target?: string | null;
|
target?: string | null;
|
||||||
disableLink?: boolean;
|
disableLink?: boolean;
|
||||||
|
showLightBox?: boolean;
|
||||||
disablePreview?: boolean;
|
disablePreview?: boolean;
|
||||||
showIndicator?: boolean;
|
showIndicator?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
target: null,
|
target: null,
|
||||||
disableLink: false,
|
disableLink: false,
|
||||||
|
showLightBox: false,
|
||||||
disablePreview: false,
|
disablePreview: false,
|
||||||
showIndicator: false,
|
showIndicator: false,
|
||||||
},
|
},
|
||||||
@ -85,6 +110,82 @@ watch(
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
async function prepareImageForPhotoswipe() {
|
||||||
|
const promise = new Promise(function (resolve) {
|
||||||
|
let image = new Image();
|
||||||
|
image.src = url;
|
||||||
|
image.onload = () => {
|
||||||
|
resolve([image.naturalWidth,image.naturalHeight]); // Resolve the promise only if the image has been loaded
|
||||||
|
}
|
||||||
|
image.onerror = () => { resolve([0,0]); };
|
||||||
|
});
|
||||||
|
await promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the function using await
|
||||||
|
const dimensions = prepareImageForPhotoswipe();
|
||||||
|
|
||||||
|
const gallery = ref(null);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const lightbox = new PhotoSwipeLightbox({
|
||||||
|
dataSource: [{
|
||||||
|
src: url,
|
||||||
|
w: dimensions[0],
|
||||||
|
h: dimensions[1],
|
||||||
|
}],
|
||||||
|
gallery: gallery.value,
|
||||||
|
children: ".avatar",
|
||||||
|
thumbSelector: ".avatar",
|
||||||
|
loop: false,
|
||||||
|
padding:
|
||||||
|
window.innerWidth > 500
|
||||||
|
? {
|
||||||
|
top: 32,
|
||||||
|
bottom: 32,
|
||||||
|
left: 32,
|
||||||
|
right: 32,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
},
|
||||||
|
imageClickAction: "close",
|
||||||
|
tapAction: "toggle-controls",
|
||||||
|
preloadFirstSlide: false,
|
||||||
|
pswpModule: PhotoSwipe,
|
||||||
|
});
|
||||||
|
|
||||||
|
lightbox.on("itemData", (ev) => {
|
||||||
|
const { itemData } = ev;
|
||||||
|
itemData.src = url;
|
||||||
|
itemData.msrc = url;
|
||||||
|
itemData.h = dimensions[1];
|
||||||
|
itemData.w = dimensions[0];
|
||||||
|
});
|
||||||
|
|
||||||
|
lightbox.on("afterInit", () => {
|
||||||
|
history.pushState(null, "", location.href);
|
||||||
|
addEventListener("popstate", close);
|
||||||
|
// This is a workaround. Not sure why, but when clicking to open, it doesn't move focus to the photoswipe. Preventing using esc to close. However when using keyboard to open it already focuses the lightbox fine.
|
||||||
|
lightbox.pswp.element.focus();
|
||||||
|
});
|
||||||
|
lightbox.on("close", () => {
|
||||||
|
removeEventListener("popstate", close);
|
||||||
|
history.back();
|
||||||
|
});
|
||||||
|
|
||||||
|
lightbox.init();
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
removeEventListener("popstate", close);
|
||||||
|
history.forward();
|
||||||
|
lightbox.pswp.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -132,6 +233,10 @@ watch(
|
|||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
|
|
||||||
|
&.showLightBox {
|
||||||
|
cursor: zoom-in;
|
||||||
|
}
|
||||||
|
|
||||||
> .inner {
|
> .inner {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
@ -114,6 +114,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<MkAvatar
|
<MkAvatar
|
||||||
class="avatar"
|
class="avatar"
|
||||||
|
:showLightBox="true"
|
||||||
:user="user"
|
:user="user"
|
||||||
:disable-preview="true"
|
:disable-preview="true"
|
||||||
:show-indicator="true"
|
:show-indicator="true"
|
||||||
|
Loading…
Reference in New Issue
Block a user