mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-23 11:04:10 +02:00
feat(frontend): 自分のプロフィールページの二次元コード(QRコード)を表示し、他の人のコードを読み取りするページを追加 (#16456)
* wip (qr.show.vue) * added to navbar * qr.show.vue * fix * added to navbar * fix size * 🎨 * 🎨 * fix div warn * fix * use * 0.25 * fix?? * fix lint * clean up * ??? * ? * fix * 🎨 * 🎨 * refactor * 🎨 * 🎨 * :ar:t * 🎨 * iphone flip * no lazy import * 🎨 * 🎨 * 🎨 * ユーザー全部flipでいいや * ✌️ * fix * fix * fix lint * 🎨 * fix type * fix: local user profile url cannot be resolved with ap/show * fix: local user url with hostname could not be resolved * chore: use common utility for checking self host * wip * 🎨 * 🎨 * fix imports * fix * fix * fix * 🎨 * fix... * set spacer-w * ✌️ * 全画面でQRを読むように * fix * 🎨 * modify navbar.ts * start/stop on vue activation * display raw content read from qr * 端末のQRをスキャンするボタンを追加 * chore * やっぱりmfmを先に表示する * 🎨 * fix 18n * QRの内容は/users/:userIdにする * add spdx * use cqh * `defineProps` is a compiler macro and no longer needs to be imported. * use MkUserName * 🎨 * 🎨 * refactor * clean up * refactor * 🎨 * Update qr.show.vue * Misskeyロゴにdrop-shadowを追加 * clean up: do not use empty css * fix os.select usage * Update qr.vue * Update qr.show.vue * Update qr.show.vue * Update get-user-menu.ts * ✌️ * Update show.ts * Update ja-JP.yml * watermark * Update CHANGELOG.md * Update qr.read.vue * Update qr.read.vue * wip * Update MkWatermarkEditorDialog.Layer.vue --------- Co-authored-by: anatawa12 <anatawa12@icloud.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
This commit is contained in:
@@ -30,22 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
<div :class="$style.controls">
|
||||
<div class="_spacer _gaps">
|
||||
<MkSelect v-model="type" :items="typeDef">
|
||||
<template #label>{{ i18n.ts._watermarkEditor.type }}</template>
|
||||
</MkSelect>
|
||||
|
||||
<div v-if="type === 'text' || type === 'image'">
|
||||
<XLayer
|
||||
v-for="(layer, i) in preset.layers"
|
||||
:key="layer.id"
|
||||
v-model:layer="preset.layers[i]"
|
||||
></XLayer>
|
||||
</div>
|
||||
<div v-else-if="type === 'advanced'" class="_gaps_s">
|
||||
<div class="_gaps_s">
|
||||
<MkFolder v-for="(layer, i) in preset.layers" :key="layer.id" :defaultOpen="false" :canPage="false">
|
||||
<template #label>
|
||||
<div v-if="layer.type === 'text'">{{ i18n.ts._watermarkEditor.text }}</div>
|
||||
<div v-if="layer.type === 'image'">{{ i18n.ts._watermarkEditor.image }}</div>
|
||||
<div v-if="layer.type === 'qr'">{{ i18n.ts._watermarkEditor.qr }}</div>
|
||||
<div v-if="layer.type === 'stripe'">{{ i18n.ts._watermarkEditor.stripe }}</div>
|
||||
<div v-if="layer.type === 'polkadot'">{{ i18n.ts._watermarkEditor.polkadot }}</div>
|
||||
<div v-if="layer.type === 'checker'">{{ i18n.ts._watermarkEditor.checker }}</div>
|
||||
@@ -95,7 +85,7 @@ function createTextLayer(): WatermarkPreset['layers'][number] {
|
||||
id: genId(),
|
||||
type: 'text',
|
||||
text: `(c) @${$i.username}`,
|
||||
align: { x: 'right', y: 'bottom' },
|
||||
align: { x: 'right', y: 'bottom', margin: 0 },
|
||||
scale: 0.3,
|
||||
angle: 0,
|
||||
opacity: 0.75,
|
||||
@@ -109,7 +99,7 @@ function createImageLayer(): WatermarkPreset['layers'][number] {
|
||||
type: 'image',
|
||||
imageId: null,
|
||||
imageUrl: null,
|
||||
align: { x: 'right', y: 'bottom' },
|
||||
align: { x: 'right', y: 'bottom', margin: 0 },
|
||||
scale: 0.3,
|
||||
angle: 0,
|
||||
opacity: 0.75,
|
||||
@@ -118,6 +108,17 @@ function createImageLayer(): WatermarkPreset['layers'][number] {
|
||||
};
|
||||
}
|
||||
|
||||
function createQrLayer(): WatermarkPreset['layers'][number] {
|
||||
return {
|
||||
id: genId(),
|
||||
type: 'qr',
|
||||
data: '',
|
||||
align: { x: 'right', y: 'bottom', margin: 0 },
|
||||
scale: 0.3,
|
||||
opacity: 1,
|
||||
};
|
||||
}
|
||||
|
||||
function createStripeLayer(): WatermarkPreset['layers'][number] {
|
||||
return {
|
||||
id: genId(),
|
||||
@@ -165,7 +166,7 @@ const props = defineProps<{
|
||||
const preset = reactive<WatermarkPreset>(deepClone(props.preset) ?? {
|
||||
id: genId(),
|
||||
name: '',
|
||||
layers: [createTextLayer()],
|
||||
layers: [],
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -187,28 +188,6 @@ async function cancel() {
|
||||
dialog.value?.close();
|
||||
}
|
||||
|
||||
const {
|
||||
model: type,
|
||||
def: typeDef,
|
||||
} = useMkSelect({
|
||||
items: [
|
||||
{ label: i18n.ts._watermarkEditor.text, value: 'text' },
|
||||
{ label: i18n.ts._watermarkEditor.image, value: 'image' },
|
||||
{ label: i18n.ts._watermarkEditor.advanced, value: 'advanced' },
|
||||
],
|
||||
initialValue: preset.layers.length > 1 ? 'advanced' : preset.layers[0].type,
|
||||
});
|
||||
|
||||
watch(type, () => {
|
||||
if (type.value === 'text') {
|
||||
preset.layers = [createTextLayer()];
|
||||
} else if (type.value === 'image') {
|
||||
preset.layers = [createImageLayer()];
|
||||
} else if (type.value === 'advanced') {
|
||||
// nop
|
||||
}
|
||||
});
|
||||
|
||||
watch(preset, async (newValue, oldValue) => {
|
||||
if (renderer != null) {
|
||||
renderer.setLayers(preset.layers);
|
||||
@@ -338,6 +317,11 @@ function addLayer(ev: MouseEvent) {
|
||||
action: () => {
|
||||
preset.layers.push(createImageLayer());
|
||||
},
|
||||
}, {
|
||||
text: i18n.ts._watermarkEditor.qr,
|
||||
action: () => {
|
||||
preset.layers.push(createQrLayer());
|
||||
},
|
||||
}, {
|
||||
text: i18n.ts._watermarkEditor.stripe,
|
||||
action: () => {
|
||||
|
||||
Reference in New Issue
Block a user