Snapshot: alpha-2026-9
This commit is contained in:
parent
9acf5a97e2
commit
d00b5c7961
241 changed files with 85546 additions and 2409 deletions
111
frontend/src/components/AuthenticatedImage.vue
Normal file
111
frontend/src/components/AuthenticatedImage.vue
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<img :src="image_data" :title="title || (owner + ':' + src)" :alt="alt" :class="imgClass"
|
||||
:width="width" :height="height" :style="{objectFit: fit}"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapActions, mapGetters} from "vuex";
|
||||
import fileCache from "../fileCache";
|
||||
|
||||
export default {
|
||||
name: "AuthenticatedImage",
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
owner: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
default: 'image'
|
||||
},
|
||||
imgClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
fallbackSrc: {
|
||||
type: String,
|
||||
default: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CjxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjEyIiBmaWxsPSIjY2VkNGRhIi8+CjxjaXJjbGUgY3g9IjEyIiBjeT0iOS41IiByPSI0IiBmaWxsPSIjZmZmZmZmIi8+CjxwYXRoIGQ9Ik00IDIwLjJDNCAxNi4yIDcuNiAxMy41IDEyIDEzLjVzOCAyLjcgOCA2Ljd2MC4zSDR2LTAuM3oiIGZpbGw9IiNmZmZmZmYiLz4KPC9zdmc+Cg=='
|
||||
},
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: null
|
||||
},
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: null
|
||||
},
|
||||
fit: {
|
||||
type: String,
|
||||
default: 'contain'
|
||||
},
|
||||
refreshKey: {
|
||||
type: [String, Number],
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
image_data: "",
|
||||
servers: [],
|
||||
lastRequestId: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["signAuth"])
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["getFriendServers"]),
|
||||
async loadImage() {
|
||||
const requestId = ++this.lastRequestId;
|
||||
if (!this.src) {
|
||||
if (requestId === this.lastRequestId) {
|
||||
this.image_data = this.fallbackSrc;
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Cached by src alone: content is hash-addressed and immutable (see fileCache.js),
|
||||
// so every instance showing the same file shares one fetch and blob.
|
||||
const url = await fileCache.get(this.src, async () => {
|
||||
this.servers = await this.getFriendServers({username: this.owner});
|
||||
const response = await this.servers.getRaw(this.signAuth, this.src);
|
||||
if (!response || !response.ok) {
|
||||
throw new Error('failed to fetch ' + this.src);
|
||||
}
|
||||
return await response.blob();
|
||||
});
|
||||
if (requestId === this.lastRequestId) {
|
||||
this.image_data = url;
|
||||
}
|
||||
} catch (_e) {
|
||||
if (requestId === this.lastRequestId) {
|
||||
this.image_data = this.fallbackSrc;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
src() {
|
||||
this.loadImage();
|
||||
},
|
||||
owner() {
|
||||
this.loadImage();
|
||||
},
|
||||
refreshKey() {
|
||||
this.loadImage();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadImage();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue