Compare commits
23 Commits
13.0.0-bet
...
13.0.0-rc.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
af6a578fa6 | ||
![]() |
73d735a1f7 | ||
![]() |
b8b1899a9f | ||
![]() |
d52f0617a1 | ||
![]() |
c730973294 | ||
![]() |
2c2e064871 | ||
![]() |
e3c39d4b52 | ||
![]() |
5da74897ae | ||
![]() |
4b1009b34e | ||
![]() |
203a7ad073 | ||
![]() |
34a7b52105 | ||
![]() |
30fc166c08 | ||
![]() |
c84d86b368 | ||
![]() |
1e5d4db0a1 | ||
![]() |
5e02f0d325 | ||
![]() |
ce5506f331 | ||
![]() |
91105845d8 | ||
![]() |
2bedc084a3 | ||
![]() |
027ef1ea4a | ||
![]() |
668aa17eef | ||
![]() |
ebf8ef22e4 | ||
![]() |
bcb5182e86 | ||
![]() |
f45059b7b1 |
@@ -76,6 +76,7 @@ You should also include the user name that made the change.
|
|||||||
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはインスタンスの招待コードを発行できるように @syuilo
|
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはインスタンスの招待コードを発行できるように @syuilo
|
||||||
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはカスタム絵文字の追加、編集、削除を行えるように @syuilo
|
- 非モデレーターでも、権限を持つロールをアサインされたユーザーはカスタム絵文字の追加、編集、削除を行えるように @syuilo
|
||||||
- ハードワードミュートの最大文字数を設定可能に @syuilo
|
- ハードワードミュートの最大文字数を設定可能に @syuilo
|
||||||
|
- Webhookの作成可能数を設定可能に @syuilo
|
||||||
- Server: signToActivityPubGet is set to true by default @syuilo
|
- Server: signToActivityPubGet is set to true by default @syuilo
|
||||||
- Server: improve syslog performance @syuilo
|
- Server: improve syslog performance @syuilo
|
||||||
- Server: Use undici instead of node-fetch and got @tamaina
|
- Server: Use undici instead of node-fetch and got @tamaina
|
||||||
@@ -132,6 +133,7 @@ You should also include the user name that made the change.
|
|||||||
- Server: 非公開のクリップのURLでOGPレンダリングされる問題を修正 @syuilo
|
- Server: 非公開のクリップのURLでOGPレンダリングされる問題を修正 @syuilo
|
||||||
- Server: アンテナタイムライン(ストリーミング)が、フォローしていないユーザーの鍵投稿も拾ってしまう @syuilo
|
- Server: アンテナタイムライン(ストリーミング)が、フォローしていないユーザーの鍵投稿も拾ってしまう @syuilo
|
||||||
- Server: follow request list api pagination @sim1222
|
- Server: follow request list api pagination @sim1222
|
||||||
|
- Server: ドライブ容量超過時のエラーが適切にレスポンスされない問題を修正 @syuilo
|
||||||
- Client: パスワードマネージャーなどでユーザー名がオートコンプリートされない問題を修正 @massongit
|
- Client: パスワードマネージャーなどでユーザー名がオートコンプリートされない問題を修正 @massongit
|
||||||
- Client: 日付形式の文字列などがカスタム絵文字として表示されるのを修正 @syuilo
|
- Client: 日付形式の文字列などがカスタム絵文字として表示されるのを修正 @syuilo
|
||||||
- Client: case insensitive emoji search @saschanaz
|
- Client: case insensitive emoji search @saschanaz
|
||||||
|
@@ -963,6 +963,7 @@ _role:
|
|||||||
driveCapacity: "ドライブ容量"
|
driveCapacity: "ドライブ容量"
|
||||||
antennaMax: "アンテナの作成可能数"
|
antennaMax: "アンテナの作成可能数"
|
||||||
wordMuteMax: "ワードミュートの最大文字数"
|
wordMuteMax: "ワードミュートの最大文字数"
|
||||||
|
webhookMax: "Webhookの作成可能数"
|
||||||
_condition:
|
_condition:
|
||||||
isLocal: "ローカルユーザー"
|
isLocal: "ローカルユーザー"
|
||||||
isRemote: "リモートユーザー"
|
isRemote: "リモートユーザー"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "13.0.0-beta.43",
|
"version": "13.0.0-rc.2",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@@ -22,6 +22,7 @@ export type RoleOptions = {
|
|||||||
driveCapacityMb: number;
|
driveCapacityMb: number;
|
||||||
antennaLimit: number;
|
antennaLimit: number;
|
||||||
wordMuteLimit: number;
|
wordMuteLimit: number;
|
||||||
|
webhookLimit: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_ROLE: RoleOptions = {
|
export const DEFAULT_ROLE: RoleOptions = {
|
||||||
@@ -33,6 +34,7 @@ export const DEFAULT_ROLE: RoleOptions = {
|
|||||||
driveCapacityMb: 100,
|
driveCapacityMb: 100,
|
||||||
antennaLimit: 5,
|
antennaLimit: 5,
|
||||||
wordMuteLimit: 200,
|
wordMuteLimit: 200,
|
||||||
|
webhookLimit: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -203,6 +205,7 @@ export class RoleService implements OnApplicationShutdown {
|
|||||||
driveCapacityMb: Math.max(...getOptionValues('driveCapacityMb')),
|
driveCapacityMb: Math.max(...getOptionValues('driveCapacityMb')),
|
||||||
antennaLimit: Math.max(...getOptionValues('antennaLimit')),
|
antennaLimit: Math.max(...getOptionValues('antennaLimit')),
|
||||||
wordMuteLimit: Math.max(...getOptionValues('wordMuteLimit')),
|
wordMuteLimit: Math.max(...getOptionValues('wordMuteLimit')),
|
||||||
|
webhookLimit: Math.max(...getOptionValues('webhookLimit')),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -62,6 +62,7 @@ export class RoleEntityService {
|
|||||||
isModerator: role.isModerator,
|
isModerator: role.isModerator,
|
||||||
canEditMembersByModerator: role.canEditMembersByModerator,
|
canEditMembersByModerator: role.canEditMembersByModerator,
|
||||||
options: roleOptions,
|
options: roleOptions,
|
||||||
|
usersCount: assigns.length,
|
||||||
...(opts.detail ? {
|
...(opts.detail ? {
|
||||||
users: this.userEntityService.packMany(assigns.map(x => x.userId), me),
|
users: this.userEntityService.packMany(assigns.map(x => x.userId), me),
|
||||||
} : {}),
|
} : {}),
|
||||||
|
@@ -90,7 +90,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const meta = await this.metaService.fetch();
|
const instance = await this.metaService.fetch();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create file
|
// Create file
|
||||||
@@ -102,8 +102,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
folderId: ps.folderId,
|
folderId: ps.folderId,
|
||||||
force: ps.force,
|
force: ps.force,
|
||||||
sensitive: ps.isSensitive,
|
sensitive: ps.isSensitive,
|
||||||
requestIp: meta.enableIpLogging ? ip : null,
|
requestIp: instance.enableIpLogging ? ip : null,
|
||||||
requestHeaders: meta.enableIpLogging ? headers : null,
|
requestHeaders: instance.enableIpLogging ? headers : null,
|
||||||
});
|
});
|
||||||
return await this.driveFileEntityService.pack(driveFile, { self: true });
|
return await this.driveFileEntityService.pack(driveFile, { self: true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -116,7 +116,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
}
|
}
|
||||||
throw new ApiError();
|
throw new ApiError();
|
||||||
} finally {
|
} finally {
|
||||||
cleanup!();
|
cleanup!();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
private queryService: QueryService,
|
private queryService: QueryService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
const query = this.queryService.makePaginationQuery(this.followRequestsRepository.createQueryBuilder('request'), ps.sinceId, ps.untilId);
|
const query = this.queryService.makePaginationQuery(this.followRequestsRepository.createQueryBuilder('request'), ps.sinceId, ps.untilId)
|
||||||
|
.andWhere('request.followeeId = :meId', { meId: me.id });
|
||||||
|
|
||||||
const requests = await query
|
const requests = await query
|
||||||
.take(ps.limit)
|
.take(ps.limit)
|
||||||
|
@@ -173,7 +173,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
if (ps.mutedWords !== undefined) {
|
if (ps.mutedWords !== undefined) {
|
||||||
// TODO: ちゃんと数える
|
// TODO: ちゃんと数える
|
||||||
const length = JSON.stringify(ps.mutedWords).length;
|
const length = JSON.stringify(ps.mutedWords).length;
|
||||||
if (length > (await this.roleService.getUserRoleOptions(user.id)).antennaLimit) {
|
if (length > (await this.roleService.getUserRoleOptions(user.id)).wordMuteLimit) {
|
||||||
throw new ApiError(meta.errors.tooManyMutedWords);
|
throw new ApiError(meta.errors.tooManyMutedWords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ import type { WebhooksRepository } from '@/models/index.js';
|
|||||||
import { webhookEventTypes } from '@/models/entities/Webhook.js';
|
import { webhookEventTypes } from '@/models/entities/Webhook.js';
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
import { RoleService } from '@/core/RoleService.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['webhooks'],
|
tags: ['webhooks'],
|
||||||
@@ -12,6 +13,14 @@ export const meta = {
|
|||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
|
||||||
kind: 'write:account',
|
kind: 'write:account',
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
tooManyWebhooks: {
|
||||||
|
message: 'You cannot create webhook any more.',
|
||||||
|
code: 'TOO_MANY_WEBHOOKS',
|
||||||
|
id: '87a9bb19-111e-4e37-81d3-a3e7426453b0',
|
||||||
|
},
|
||||||
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
@@ -38,8 +47,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
|||||||
|
|
||||||
private idService: IdService,
|
private idService: IdService,
|
||||||
private globalEventService: GlobalEventService,
|
private globalEventService: GlobalEventService,
|
||||||
|
private roleService: RoleService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
const currentWebhooksCount = await this.webhooksRepository.countBy({
|
||||||
|
userId: me.id,
|
||||||
|
});
|
||||||
|
if (currentWebhooksCount > (await this.roleService.getUserRoleOptions(me.id)).webhookLimit) {
|
||||||
|
throw new ApiError(meta.errors.tooManyWebhooks);
|
||||||
|
}
|
||||||
|
|
||||||
const webhook = await this.webhooksRepository.insert({
|
const webhook = await this.webhooksRepository.insert({
|
||||||
id: this.idService.genId(),
|
id: this.idService.genId(),
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<svg class="mbcofsoe" viewBox="0 0 10 10" preserveAspectRatio="none">
|
<svg :class="$style.root" viewBox="0 0 10 10" preserveAspectRatio="none">
|
||||||
<template v-if="props.graduations === 'dots'">
|
<template v-if="props.graduations === 'dots'">
|
||||||
<circle
|
<circle
|
||||||
v-for="(angle, i) in graduationsMajor"
|
v-for="(angle, i) in graduationsMajor"
|
||||||
@@ -39,8 +39,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<line
|
<line
|
||||||
class="s"
|
:class="[$style.s, { [$style.animate]: !disableSAnimate && sAnimation !== 'none', [$style.elastic]: sAnimation === 'elastic', [$style.easeOut]: sAnimation === 'easeOut' }]"
|
||||||
:class="{ animate: !disableSAnimate && sAnimation !== 'none', elastic: sAnimation === 'elastic', easeOut: sAnimation === 'easeOut' }"
|
|
||||||
:x1="5 - (0 * (sHandLengthRatio * handsTailLength))"
|
:x1="5 - (0 * (sHandLengthRatio * handsTailLength))"
|
||||||
:y1="5 + (1 * (sHandLengthRatio * handsTailLength))"
|
:y1="5 + (1 * (sHandLengthRatio * handsTailLength))"
|
||||||
:x2="5 + (0 * ((sHandLengthRatio * 5) - handsPadding))"
|
:x2="5 + (0 * ((sHandLengthRatio * 5) - handsPadding))"
|
||||||
@@ -205,21 +204,21 @@ onBeforeUnmount(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.mbcofsoe {
|
.root {
|
||||||
display: block;
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
> .s {
|
.s {
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
transform-origin: 50% 50%;
|
transform-origin: 50% 50%;
|
||||||
|
|
||||||
&.animate.elastic {
|
&.animate.elastic {
|
||||||
transition: transform .2s cubic-bezier(.4,2.08,.55,.44);
|
transition: transform .2s cubic-bezier(.4,2.08,.55,.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.animate.easeOut {
|
&.animate.easeOut {
|
||||||
transition: transform .7s cubic-bezier(0,.7,.3,1);
|
transition: transform .7s cubic-bezier(0,.7,.3,1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="nrvgflfu _button" @click="toggle">
|
<button class="_button" :class="$style.root" @click="toggle">
|
||||||
<b>{{ modelValue ? i18n.ts._cw.hide : i18n.ts._cw.show }}</b>
|
<b>{{ modelValue ? i18n.ts._cw.hide : i18n.ts._cw.show }}</b>
|
||||||
<span v-if="!modelValue">{{ label }}</span>
|
<span v-if="!modelValue" :class="$style.label">{{ label }}</span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -34,8 +34,8 @@ const toggle = () => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.nrvgflfu {
|
.root {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
@@ -46,17 +46,17 @@ const toggle = () => {
|
|||||||
&:hover {
|
&:hover {
|
||||||
background: var(--cwHoverBg);
|
background: var(--cwHoverBg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> span {
|
.label {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: '(';
|
content: '(';
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: ')';
|
content: ')';
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="zjobosdg">
|
<span>
|
||||||
<span v-text="hh"></span>
|
<span v-text="hh"></span>
|
||||||
<span class="colon" :class="{ showColon }">:</span>
|
<span :class="[$style.colon, { [$style.showColon]: showColon }]">:</span>
|
||||||
<span v-text="mm"></span>
|
<span v-text="mm"></span>
|
||||||
<span v-if="showS" class="colon" :class="{ showColon }">:</span>
|
<span v-if="showS" :class="[$style.colon, { [$style.showColon]: showColon }]">:</span>
|
||||||
<span v-if="showS" v-text="ss"></span>
|
<span v-if="showS" v-text="ss"></span>
|
||||||
<span v-if="showMs" class="colon" :class="{ showColon }">:</span>
|
<span v-if="showMs" :class="[$style.colon, { [$style.showColon]: showColon }]">:</span>
|
||||||
<span v-if="showMs" v-text="ms"></span>
|
<span v-if="showMs" v-text="ms"></span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -62,16 +62,14 @@ onUnmounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.zjobosdg {
|
.colon {
|
||||||
> .colon {
|
opacity: 0;
|
||||||
opacity: 0;
|
transition: opacity 1s ease;
|
||||||
transition: opacity 1s ease;
|
|
||||||
|
|
||||||
&.showColon {
|
&.showColon {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity 0s;
|
transition: opacity 0s;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,17 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="rootEl" class="dwzlatin" :class="{ opened }">
|
<div ref="rootEl" :class="[$style.root, { [$style.opened]: opened }]">
|
||||||
<div class="header _button" @click="toggle">
|
<div :class="$style.header" class="_button" @click="toggle">
|
||||||
<span class="icon"><slot name="icon"></slot></span>
|
<span :class="$style.headerIcon"><slot name="icon"></slot></span>
|
||||||
<span class="text"><slot name="label"></slot></span>
|
<span :class="$style.headerText"><slot name="label"></slot></span>
|
||||||
<span class="right">
|
<span :class="$style.headerRight">
|
||||||
<span class="text"><slot name="suffix"></slot></span>
|
<span :class="$style.headerRightText"><slot name="suffix"></slot></span>
|
||||||
<i v-if="opened" class="ti ti-chevron-up icon"></i>
|
<i v-if="opened" class="ti ti-chevron-up icon"></i>
|
||||||
<i v-else class="ti ti-chevron-down icon"></i>
|
<i v-else class="ti ti-chevron-down icon"></i>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="openedAtLeastOnce" class="body" :class="{ bgSame }" :style="{ maxHeight: maxHeight ? `${maxHeight}px` : null }">
|
<div v-if="openedAtLeastOnce" :class="[$style.body, { [$style.bgSame]: bgSame }]" :style="{ maxHeight: maxHeight ? `${maxHeight}px` : null }">
|
||||||
<Transition
|
<Transition
|
||||||
:name="$store.state.animation ? 'folder-toggle' : ''"
|
:enter-active-class="$store.state.animation ? $style.transition_toggle_enterActive : ''"
|
||||||
|
:leave-active-class="$store.state.animation ? $style.transition_toggle_leaveActive : ''"
|
||||||
|
:enter-from-class="$store.state.animation ? $style.transition_toggle_enterFrom : ''"
|
||||||
|
:leave-to-class="$store.state.animation ? $style.transition_toggle_leaveTo : ''"
|
||||||
@enter="enter"
|
@enter="enter"
|
||||||
@after-enter="afterEnter"
|
@after-enter="afterEnter"
|
||||||
@leave="leave"
|
@leave="leave"
|
||||||
@@ -94,85 +97,88 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.folder-toggle-enter-active, .folder-toggle-leave-active {
|
.transition_toggle_enterActive,
|
||||||
|
.transition_toggle_leaveActive {
|
||||||
overflow-y: clip;
|
overflow-y: clip;
|
||||||
transition: opacity 0.3s, height 0.3s, transform 0.3s !important;
|
transition: opacity 0.3s, height 0.3s, transform 0.3s !important;
|
||||||
}
|
}
|
||||||
.folder-toggle-enter-from, .folder-toggle-leave-to {
|
.transition_toggle_enterFrom,
|
||||||
|
.transition_toggle_leaveTo {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dwzlatin {
|
.root {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
> .header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 10px 14px 10px 14px;
|
|
||||||
background: var(--buttonBg);
|
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
background: var(--buttonHoverBg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: var(--accent);
|
|
||||||
background: var(--buttonHoverBg);
|
|
||||||
}
|
|
||||||
|
|
||||||
> .icon {
|
|
||||||
margin-right: 0.75em;
|
|
||||||
flex-shrink: 0;
|
|
||||||
text-align: center;
|
|
||||||
opacity: 0.8;
|
|
||||||
|
|
||||||
&:empty {
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
& + .text {
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .text {
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
padding-right: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .right {
|
|
||||||
margin-left: auto;
|
|
||||||
opacity: 0.7;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
> .text:not(:empty) {
|
|
||||||
margin-right: 0.75em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .body {
|
|
||||||
background: var(--panel);
|
|
||||||
border-radius: 0 0 6px 6px;
|
|
||||||
container-type: inline-size;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
&.bgSame {
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.opened {
|
&.opened {
|
||||||
> .header {
|
> .header {
|
||||||
border-radius: 6px 6px 0 0;
|
border-radius: 6px 6px 0 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 9px 12px 9px 12px;
|
||||||
|
background: var(--buttonBg);
|
||||||
|
border-radius: 6px;
|
||||||
|
transition: border-radius 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--buttonHoverBg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: var(--accent);
|
||||||
|
background: var(--buttonHoverBg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerIcon {
|
||||||
|
margin-right: 0.75em;
|
||||||
|
flex-shrink: 0;
|
||||||
|
text-align: center;
|
||||||
|
opacity: 0.8;
|
||||||
|
|
||||||
|
&:empty {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
& + .headerText {
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerText {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerRight {
|
||||||
|
margin-left: auto;
|
||||||
|
opacity: 0.7;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerRightText:not(:empty) {
|
||||||
|
margin-right: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
background: var(--panel);
|
||||||
|
border-radius: 0 0 6px 6px;
|
||||||
|
container-type: inline-size;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
&.bgSame {
|
||||||
|
background: var(--bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,8 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<Transition :name="transitionName" :duration="transitionDuration" appear @after-leave="emit('closed')" @enter="emit('opening')" @after-enter="onOpened">
|
<Transition
|
||||||
<div v-show="manualShowing != null ? manualShowing : showing" v-hotkey.global="keymap" class="qzhlnise" :class="{ drawer: type === 'drawer', dialog: type === 'dialog' || type === 'dialog:top', popup: type === 'popup' }" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
|
:name="transitionName"
|
||||||
<div class="bg _modalBg" :class="{ transparent: transparentBg && (type === 'popup') }" :style="{ zIndex }" @click="onBgClick" @mousedown="onBgClick" @contextmenu.prevent.stop="() => {}"></div>
|
:enter-active-class="$style['transition_' + transitionName + '_enterActive']"
|
||||||
<div ref="content" class="content" :class="{ fixed, top: type === 'dialog:top' }" :style="{ zIndex }" @click.self="onBgClick">
|
:leave-active-class="$style['transition_' + transitionName + '_leaveActive']"
|
||||||
|
:enter-from-class="$style['transition_' + transitionName + '_enterFrom']"
|
||||||
|
:leave-to-class="$style['transition_' + transitionName + '_leaveTo']"
|
||||||
|
:duration="transitionDuration" appear @after-leave="emit('closed')" @enter="emit('opening')" @after-enter="onOpened"
|
||||||
|
>
|
||||||
|
<div v-show="manualShowing != null ? manualShowing : showing" v-hotkey.global="keymap" :class="[$style.root, { [$style.drawer]: type === 'drawer', [$style.dialog]: type === 'dialog' || type === 'dialog:top', [$style.popup]: type === 'popup' }]" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
|
||||||
|
<div class="_modalBg" :class="[$style.bg, { [$style.bgTransparent]: transparentBg && (type === 'popup') }]" :style="{ zIndex }" @click="onBgClick" @mousedown="onBgClick" @contextmenu.prevent.stop="() => {}"></div>
|
||||||
|
<div ref="content" :class="[$style.content, { [$style.fixed]: fixed, [$style.top]: type === 'dialog:top' }]" :style="{ zIndex }" @click.self="onBgClick">
|
||||||
<slot :max-height="maxHeight" :type="type"></slot>
|
<slot :max-height="maxHeight" :type="type"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -280,8 +287,9 @@ defineExpose({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.send-enter-active, .send-leave-active {
|
.transition_send_enterActive,
|
||||||
|
.transition_send_leaveActive {
|
||||||
> .bg {
|
> .bg {
|
||||||
transition: opacity 0.3s !important;
|
transition: opacity 0.3s !important;
|
||||||
}
|
}
|
||||||
@@ -291,7 +299,8 @@ defineExpose({
|
|||||||
transition: opacity 0.3s ease-in, transform 0.3s cubic-bezier(.5,-0.5,1,.5) !important;
|
transition: opacity 0.3s ease-in, transform 0.3s cubic-bezier(.5,-0.5,1,.5) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.send-enter-from, .send-leave-to {
|
.transition_send_enterFrom,
|
||||||
|
.transition_send_leaveTo {
|
||||||
> .bg {
|
> .bg {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -303,7 +312,8 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-enter-active, .modal-leave-active {
|
.transition_modal_enterActive,
|
||||||
|
.transition_modal_leaveActive {
|
||||||
> .bg {
|
> .bg {
|
||||||
transition: opacity 0.2s !important;
|
transition: opacity 0.2s !important;
|
||||||
}
|
}
|
||||||
@@ -313,7 +323,8 @@ defineExpose({
|
|||||||
transition: opacity 0.2s, transform 0.2s !important;
|
transition: opacity 0.2s, transform 0.2s !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.modal-enter-from, .modal-leave-to {
|
.transition_modal_enterFrom,
|
||||||
|
.transition_modal_leaveTo {
|
||||||
> .bg {
|
> .bg {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -326,7 +337,8 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-popup-enter-active, .modal-popup-leave-active {
|
.transition_modal-popup_enterActive,
|
||||||
|
.transition_modal-popup_leaveActive {
|
||||||
> .bg {
|
> .bg {
|
||||||
transition: opacity 0.1s !important;
|
transition: opacity 0.1s !important;
|
||||||
}
|
}
|
||||||
@@ -336,7 +348,8 @@ defineExpose({
|
|||||||
transition: opacity 0.1s cubic-bezier(0, 0, 0.2, 1), transform 0.1s cubic-bezier(0, 0, 0.2, 1) !important;
|
transition: opacity 0.1s cubic-bezier(0, 0, 0.2, 1), transform 0.1s cubic-bezier(0, 0, 0.2, 1) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.modal-popup-enter-from, .modal-popup-leave-to {
|
.transition_modal-popup_enterFrom,
|
||||||
|
.transition_modal-popup_leaveTo {
|
||||||
> .bg {
|
> .bg {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -349,7 +362,7 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-drawer-enter-active {
|
.transition_modal-drawer_enterActive {
|
||||||
> .bg {
|
> .bg {
|
||||||
transition: opacity 0.2s !important;
|
transition: opacity 0.2s !important;
|
||||||
}
|
}
|
||||||
@@ -358,7 +371,7 @@ defineExpose({
|
|||||||
transition: transform 0.2s cubic-bezier(0,.5,0,1) !important;
|
transition: transform 0.2s cubic-bezier(0,.5,0,1) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.modal-drawer-leave-active {
|
.transition_modal-drawer_leaveActive {
|
||||||
> .bg {
|
> .bg {
|
||||||
transition: opacity 0.2s !important;
|
transition: opacity 0.2s !important;
|
||||||
}
|
}
|
||||||
@@ -367,7 +380,8 @@ defineExpose({
|
|||||||
transition: transform 0.2s cubic-bezier(0,.5,0,1) !important;
|
transition: transform 0.2s cubic-bezier(0,.5,0,1) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.modal-drawer-enter-from, .modal-drawer-leave-to {
|
.transition_modal-drawer_enterFrom,
|
||||||
|
.transition_modal-drawer_leaveTo {
|
||||||
> .bg {
|
> .bg {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -378,15 +392,7 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.qzhlnise {
|
.root {
|
||||||
> .bg {
|
|
||||||
&.transparent {
|
|
||||||
background: transparent;
|
|
||||||
-webkit-backdrop-filter: none;
|
|
||||||
backdrop-filter: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.dialog {
|
&.dialog {
|
||||||
> .content {
|
> .content {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -408,12 +414,12 @@ defineExpose({
|
|||||||
mask-image: linear-gradient(0deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 16px, rgba(0,0,0,1) calc(100% - 16px), rgba(0,0,0,0) 100%);
|
mask-image: linear-gradient(0deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 16px, rgba(0,0,0,1) calc(100% - 16px), rgba(0,0,0,0) 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
> ::v-deep(*) {
|
&:global > * {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.top {
|
&.top {
|
||||||
> ::v-deep(*) {
|
&:global > * {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,11 +451,18 @@ defineExpose({
|
|||||||
right: 0;
|
right: 0;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|
||||||
> ::v-deep(*) {
|
&:global > * {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg {
|
||||||
|
&.bgTransparent {
|
||||||
|
background: transparent;
|
||||||
|
-webkit-backdrop-filter: none;
|
||||||
|
backdrop-filter: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<MkA v-adaptive-bg :to="`/admin/roles/${role.id}`" class="_panel" :class="$style.root" tabindex="-1" :style="{ '--color': role.color }">
|
<MkA v-adaptive-bg :to="`/admin/roles/${role.id}`" class="_panel" :class="$style.root" tabindex="-1" :style="{ '--color': role.color }">
|
||||||
<div :class="$style.title">{{ role.name }}</div>
|
<div :class="$style.title">
|
||||||
|
<span :class="$style.name">{{ role.name }}</span>
|
||||||
|
<span v-if="role.target === 'manual'" :class="$style.users">{{ role.usersCount }} users</span>
|
||||||
|
<span v-else-if="role.target === 'conditional'" :class="$style.users">({{ i18n.ts._role.conditional }})</span>
|
||||||
|
</div>
|
||||||
<div :class="$style.description">{{ role.description }}</div>
|
<div :class="$style.description">{{ role.description }}</div>
|
||||||
</MkA>
|
</MkA>
|
||||||
</template>
|
</template>
|
||||||
@@ -9,6 +13,7 @@
|
|||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
role: any;
|
role: any;
|
||||||
@@ -23,9 +28,18 @@ const props = defineProps<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.users {
|
||||||
|
margin-left: auto;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-toast">
|
<div>
|
||||||
<Transition :name="$store.state.animation ? 'toast' : ''" appear @after-leave="emit('closed')">
|
<Transition
|
||||||
<div v-if="showing" class="body _acrylic" :style="{ zIndex }">
|
:enter-active-class="$store.state.animation ? $style.transition_toast_enterActive : ''"
|
||||||
<div class="message">
|
:leave-active-class="$store.state.animation ? $style.transition_toast_leaveActive : ''"
|
||||||
|
:enter-from-class="$store.state.animation ? $style.transition_toast_enterFrom : ''"
|
||||||
|
:leave-to-class="$store.state.animation ? $style.transition_toast_leaveTo : ''"
|
||||||
|
appear @after-leave="emit('closed')"
|
||||||
|
>
|
||||||
|
<div v-if="showing" class="_acrylic" :class="$style.root" :style="{ zIndex }">
|
||||||
|
<div style="padding: 16px 24px;">
|
||||||
{{ message }}
|
{{ message }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,35 +38,31 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.toast-enter-active, .toast-leave-active {
|
.transition_toast_enterActive,
|
||||||
|
.transition_toast_leaveActive {
|
||||||
transition: opacity 0.3s, transform 0.3s !important;
|
transition: opacity 0.3s, transform 0.3s !important;
|
||||||
}
|
}
|
||||||
.toast-enter-from, .toast-leave-to {
|
.transition_toast_enterFrom,
|
||||||
|
.transition_toast_leaveTo {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mk-toast {
|
> .root {
|
||||||
> .body {
|
position: fixed;
|
||||||
position: fixed;
|
left: 0;
|
||||||
left: 0;
|
right: 0;
|
||||||
right: 0;
|
top: 0;
|
||||||
top: 0;
|
margin: 0 auto;
|
||||||
margin: 0 auto;
|
margin-top: 16px;
|
||||||
margin-top: 16px;
|
min-width: 300px;
|
||||||
min-width: 300px;
|
max-width: calc(100% - 32px);
|
||||||
max-width: calc(100% - 32px);
|
width: min-content;
|
||||||
width: min-content;
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
||||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
border-radius: 8px;
|
||||||
border-radius: 8px;
|
overflow: clip;
|
||||||
overflow: clip;
|
text-align: center;
|
||||||
text-align: center;
|
pointer-events: none;
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
> .message {
|
|
||||||
padding: 16px 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<MkModal ref="modal" :z-priority="'middle'" @click="$refs.modal.close()" @closed="$emit('closed')">
|
<MkModal ref="modal" :z-priority="'middle'" @click="$refs.modal.close()" @closed="$emit('closed')">
|
||||||
<div class="ewlycnyt">
|
<div :class="$style.root">
|
||||||
<div class="title"><MkSparkle>{{ i18n.ts.misskeyUpdated }}</MkSparkle></div>
|
<div :class="$style.title"><MkSparkle>{{ i18n.ts.misskeyUpdated }}</MkSparkle></div>
|
||||||
<div class="version">✨{{ version }}🚀</div>
|
<div :class="$style.version">✨{{ version }}🚀</div>
|
||||||
<MkButton full @click="whatIsNew">{{ i18n.ts.whatIsNew }}</MkButton>
|
<MkButton full @click="whatIsNew">{{ i18n.ts.whatIsNew }}</MkButton>
|
||||||
<MkButton class="gotIt" primary full @click="$refs.modal.close()">{{ i18n.ts.gotIt }}</MkButton>
|
<MkButton :class="$style.gotIt" primary full @click="$refs.modal.close()">{{ i18n.ts.gotIt }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</MkModal>
|
</MkModal>
|
||||||
</template>
|
</template>
|
||||||
@@ -32,8 +32,8 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.ewlycnyt {
|
.root {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
@@ -42,17 +42,17 @@ onMounted(() => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
> .title {
|
.title {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .version {
|
.version {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .gotIt {
|
.gotIt {
|
||||||
margin: 8px 0 0 0;
|
margin: 8px 0 0 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,38 +1,38 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="playerEnabled" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
<div v-if="playerEnabled" :class="$style.player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
||||||
<button class="disablePlayer" :title="i18n.ts.disablePlayer" @click="playerEnabled = false"><i class="ti ti-x"></i></button>
|
<button :class="$style.disablePlayer" :title="i18n.ts.disablePlayer" @click="playerEnabled = false"><i class="ti ti-x"></i></button>
|
||||||
<iframe :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen/>
|
<iframe :class="$style.playerIframe" :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tweetId && tweetExpanded" ref="twitter" class="twitter">
|
<div v-else-if="tweetId && tweetExpanded" ref="twitter" :class="$style.twitter">
|
||||||
<iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${$store.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe>
|
<iframe ref="tweet" scrolling="no" frameborder="no" :style="{ position: 'relative', width: '100%', height: `${tweetHeight}px` }" :src="`https://platform.twitter.com/embed/index.html?embedId=${embedId}&hideCard=false&hideThread=false&lang=en&theme=${$store.state.darkMode ? 'dark' : 'light'}&id=${tweetId}`"></iframe>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="mk-url-preview">
|
<div v-else :class="$style.urlPreview">
|
||||||
<component :is="self ? 'MkA' : 'a'" class="link" :class="{ compact }" :[attr]="self ? url.substr(local.length) : url" rel="nofollow noopener" :target="target" :title="url">
|
<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substr(local.length) : url" rel="nofollow noopener" :target="target" :title="url">
|
||||||
<div v-if="thumbnail" class="thumbnail" :style="`background-image: url('${thumbnail}')`">
|
<div v-if="thumbnail" :class="$style.thumbnail" :style="`background-image: url('${thumbnail}')`">
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article :class="$style.body">
|
||||||
<header>
|
<header :class="$style.header">
|
||||||
<h1 v-if="unknownUrl">{{ url }}</h1>
|
<h1 v-if="unknownUrl" :class="$style.title">{{ url }}</h1>
|
||||||
<h1 v-else-if="fetching"><MkEllipsis/></h1>
|
<h1 v-else-if="fetching" :class="$style.title"><MkEllipsis/></h1>
|
||||||
<h1 v-else :title="title">{{ title }}</h1>
|
<h1 v-else :class="$style.title" :title="title">{{ title }}</h1>
|
||||||
</header>
|
</header>
|
||||||
<p v-if="unknownUrl">{{ i18n.ts.cannotLoad }}</p>
|
<p v-if="unknownUrl" :class="$style.text">{{ i18n.ts.cannotLoad }}</p>
|
||||||
<p v-else-if="fetching"><MkEllipsis/></p>
|
<p v-else-if="fetching" :class="$style.text"><MkEllipsis/></p>
|
||||||
<p v-else-if="description" :title="description">{{ description.length > 85 ? description.slice(0, 85) + '…' : description }}</p>
|
<p v-else-if="description" :class="$style.text" :title="description">{{ description.length > 85 ? description.slice(0, 85) + '…' : description }}</p>
|
||||||
<footer>
|
<footer :class="$style.footer">
|
||||||
<img v-if="icon" class="icon" :src="icon"/>
|
<img v-if="icon" :class="$style.siteIcon" :src="icon"/>
|
||||||
<p v-if="unknownUrl">?</p>
|
<p v-if="unknownUrl" :class="$style.siteName">?</p>
|
||||||
<p v-else-if="fetching"><MkEllipsis/></p>
|
<p v-else-if="fetching" :class="$style.siteName"><MkEllipsis/></p>
|
||||||
<p v-else :title="sitename">{{ sitename }}</p>
|
<p v-else :class="$style.siteName" :title="sitename">{{ sitename }}</p>
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
</component>
|
</component>
|
||||||
<div v-if="tweetId" class="action">
|
<div v-if="tweetId" :class="$style.action">
|
||||||
<MkButton :small="true" inline @click="tweetExpanded = true">
|
<MkButton :small="true" inline @click="tweetExpanded = true">
|
||||||
<i class="ti ti-brand-twitter"></i> {{ i18n.ts.expandTweet }}
|
<i class="ti ti-brand-twitter"></i> {{ i18n.ts.expandTweet }}
|
||||||
</MkButton>
|
</MkButton>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!playerEnabled && player.url" class="action">
|
<div v-if="!playerEnabled && player.url" :class="$style.action">
|
||||||
<MkButton :small="true" inline @click="playerEnabled = true">
|
<MkButton :small="true" inline @click="playerEnabled = true">
|
||||||
<i class="ti ti-player-play"></i> {{ i18n.ts.enablePlayer }}
|
<i class="ti ti-player-play"></i> {{ i18n.ts.enablePlayer }}
|
||||||
</MkButton>
|
</MkButton>
|
||||||
@@ -136,197 +136,198 @@ onUnmounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.player {
|
.player {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
> button {
|
.disablePlayer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -1.5em;
|
top: -1.5em;
|
||||||
right: 0;
|
right: 0;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
width: 1.5em;
|
width: 1.5em;
|
||||||
height: 1.5em;
|
height: 1.5em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
background: rgba(128, 128, 128, 0.2);
|
background: rgba(128, 128, 128, 0.2);
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> iframe {
|
|
||||||
height: 100%;
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mk-url-preview {
|
.playerIframe {
|
||||||
> .link {
|
height: 100%;
|
||||||
position: relative;
|
left: 0;
|
||||||
display: block;
|
position: absolute;
|
||||||
font-size: 14px;
|
top: 0;
|
||||||
box-shadow: 0 0 0 1px var(--divider);
|
width: 100%;
|
||||||
border-radius: 8px;
|
}
|
||||||
overflow: clip;
|
|
||||||
|
|
||||||
&:hover {
|
.twitter {
|
||||||
text-decoration: none;
|
|
||||||
border-color: rgba(0, 0, 0, 0.2);
|
|
||||||
|
|
||||||
> article > header > h1 {
|
}
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .thumbnail {
|
.urlPreview {
|
||||||
position: absolute;
|
}
|
||||||
width: 100px;
|
|
||||||
height: 100%;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
& + article {
|
.link {
|
||||||
left: 100px;
|
position: relative;
|
||||||
width: calc(100% - 100px);
|
display: block;
|
||||||
}
|
font-size: 14px;
|
||||||
}
|
box-shadow: 0 0 0 1px var(--divider);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: clip;
|
||||||
|
|
||||||
> article {
|
&:hover {
|
||||||
position: relative;
|
text-decoration: none;
|
||||||
box-sizing: border-box;
|
border-color: rgba(0, 0, 0, 0.2);
|
||||||
padding: 16px;
|
|
||||||
|
|
||||||
> header {
|
> .body > .header > .title {
|
||||||
margin-bottom: 8px;
|
text-decoration: underline;
|
||||||
|
|
||||||
> h1 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
> footer {
|
|
||||||
margin-top: 8px;
|
|
||||||
height: 16px;
|
|
||||||
|
|
||||||
> img {
|
|
||||||
display: inline-block;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin-right: 4px;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
> p {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0;
|
|
||||||
color: var(--urlPreviewInfo);
|
|
||||||
font-size: 0.8em;
|
|
||||||
line-height: 16px;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.compact {
|
|
||||||
> article {
|
|
||||||
> header h1, p, footer {
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .action {
|
&.compact {
|
||||||
display: flex;
|
> .body {
|
||||||
gap: 6px;
|
> .header .title, .text, .footer {
|
||||||
flex-wrap: wrap;
|
overflow: hidden;
|
||||||
margin-top: 6px;
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
position: absolute;
|
||||||
|
width: 100px;
|
||||||
|
height: 100%;
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
& + .body {
|
||||||
|
left: 100px;
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 8px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.siteIcon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-right: 4px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.siteName {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
color: var(--urlPreviewInfo);
|
||||||
|
font-size: 0.8em;
|
||||||
|
line-height: 16px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
@container (max-width: 400px) {
|
@container (max-width: 400px) {
|
||||||
.mk-url-preview {
|
.link {
|
||||||
> .link {
|
font-size: 12px;
|
||||||
font-size: 12px;
|
}
|
||||||
|
|
||||||
> .thumbnail {
|
.thumbnail {
|
||||||
height: 80px;
|
height: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> article {
|
.body {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@container (max-width: 350px) {
|
@container (max-width: 350px) {
|
||||||
.mk-url-preview {
|
.link {
|
||||||
> .link {
|
font-size: 10px;
|
||||||
font-size: 10px;
|
|
||||||
|
|
||||||
|
&.compact {
|
||||||
> .thumbnail {
|
> .thumbnail {
|
||||||
height: 70px;
|
position: absolute;
|
||||||
|
width: 56px;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
> article {
|
> .body {
|
||||||
padding: 8px;
|
left: 56px;
|
||||||
|
width: calc(100% - 56px);
|
||||||
|
padding: 4px;
|
||||||
|
|
||||||
> header {
|
> .header {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> footer {
|
> .footer {
|
||||||
margin-top: 4px;
|
margin-top: 2px;
|
||||||
|
|
||||||
> img {
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.compact {
|
|
||||||
> .thumbnail {
|
|
||||||
position: absolute;
|
|
||||||
width: 56px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
> article {
|
|
||||||
left: 56px;
|
|
||||||
width: calc(100% - 56px);
|
|
||||||
padding: 4px;
|
|
||||||
|
|
||||||
> header {
|
|
||||||
margin-bottom: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> footer {
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.siteIcon {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<MkTooltip ref="tooltip" :showing="showing" :target-element="targetElement" :max-width="250" @closed="emit('closed')">
|
<MkTooltip ref="tooltip" :showing="showing" :target-element="targetElement" :max-width="250" @closed="emit('closed')">
|
||||||
<div class="beaffaef">
|
<div :class="$style.root">
|
||||||
<div v-for="u in users" :key="u.id" class="user">
|
<div v-for="u in users" :key="u.id" :class="$style.user">
|
||||||
<MkAvatar class="avatar" :user="u"/>
|
<MkAvatar :class="$style.avatar" :user="u"/>
|
||||||
<MkUserName class="name" :user="u" :nowrap="true"/>
|
<MkUserName :class="$style.name" :user="u" :nowrap="true"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="users.length < count" class="omitted">+{{ count - users.length }}</div>
|
<div v-if="users.length < count" :class="$style.omitted">+{{ count - users.length }}</div>
|
||||||
</div>
|
</div>
|
||||||
</MkTooltip>
|
</MkTooltip>
|
||||||
</template>
|
</template>
|
||||||
@@ -26,26 +26,34 @@ const emit = defineEmits<{
|
|||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.beaffaef {
|
.root {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
> .user {
|
.user {
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
}
|
|
||||||
|
|
||||||
> .avatar {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
margin-right: 3px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.omitted {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,34 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<Transition :name="$store.state.animation ? 'window' : ''" appear @after-leave="$emit('closed')">
|
<Transition
|
||||||
<div v-if="showing" ref="rootEl" class="ebkgocck" :class="{ maximized }">
|
:enter-active-class="$store.state.animation ? $style.transition_window_enterActive : ''"
|
||||||
<div class="body _shadow" @mousedown="onBodyMousedown" @keydown="onKeydown">
|
:leave-active-class="$store.state.animation ? $style.transition_window_leaveActive : ''"
|
||||||
<div class="header" :class="{ mini }" @contextmenu.prevent.stop="onContextmenu">
|
:enter-from-class="$store.state.animation ? $style.transition_window_enterFrom : ''"
|
||||||
<span class="left">
|
:leave-to-class="$store.state.animation ? $style.transition_window_leaveTo : ''"
|
||||||
<button v-for="button in buttonsLeft" v-tooltip="button.title" class="button _button" :class="{ highlighted: button.highlighted }" @click="button.onClick"><i :class="button.icon"></i></button>
|
appear
|
||||||
|
@after-leave="$emit('closed')"
|
||||||
|
>
|
||||||
|
<div v-if="showing" ref="rootEl" :class="[$style.root, { [$style.maximized]: maximized }]">
|
||||||
|
<div :class="$style.body" class="_shadow" @mousedown="onBodyMousedown" @keydown="onKeydown">
|
||||||
|
<div :class="[$style.header, { [$style.mini]: mini }]" @contextmenu.prevent.stop="onContextmenu">
|
||||||
|
<span :class="$style.headerLeft">
|
||||||
|
<button v-for="button in buttonsLeft" v-tooltip="button.title" class="_button" :class="[$style.headerButton, { [$style.highlighted]: button.highlighted }]" @click="button.onClick"><i :class="button.icon"></i></button>
|
||||||
</span>
|
</span>
|
||||||
<span class="title" @mousedown.prevent="onHeaderMousedown" @touchstart.prevent="onHeaderMousedown">
|
<span :class="$style.headerTitle" @mousedown.prevent="onHeaderMousedown" @touchstart.prevent="onHeaderMousedown">
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
</span>
|
</span>
|
||||||
<span class="right">
|
<span :class="$style.headerRight">
|
||||||
<button v-for="button in buttonsRight" v-tooltip="button.title" class="button _button" :class="{ highlighted: button.highlighted }" @click="button.onClick"><i :class="button.icon"></i></button>
|
<button v-for="button in buttonsRight" v-tooltip="button.title" class="_button" :class="[$style.headerButton, { [$style.highlighted]: button.highlighted }]" @click="button.onClick"><i :class="button.icon"></i></button>
|
||||||
<button v-if="canResize && maximized" v-tooltip="i18n.ts.windowRestore" class="button _button" @click="unMaximize()"><i class="ti ti-picture-in-picture"></i></button>
|
<button v-if="canResize && maximized" v-tooltip="i18n.ts.windowRestore" class="_button" :class="$style.headerButton" @click="unMaximize()"><i class="ti ti-picture-in-picture"></i></button>
|
||||||
<button v-else-if="canResize && !maximized" v-tooltip="i18n.ts.windowMaximize" class="button _button" @click="maximize()"><i class="ti ti-rectangle"></i></button>
|
<button v-else-if="canResize && !maximized" v-tooltip="i18n.ts.windowMaximize" class="_button" :class="$style.headerButton" @click="maximize()"><i class="ti ti-rectangle"></i></button>
|
||||||
<button v-if="closeButton" v-tooltip="i18n.ts.close" class="button _button" @click="close()"><i class="ti ti-x"></i></button>
|
<button v-if="closeButton" v-tooltip="i18n.ts.close" class="_button" :class="$style.headerButton" @click="close()"><i class="ti ti-x"></i></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div :class="$style.content">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="canResize">
|
<template v-if="canResize">
|
||||||
<div class="handle top" @mousedown.prevent="onTopHandleMousedown"></div>
|
<div :class="$style.handleTop" @mousedown.prevent="onTopHandleMousedown"></div>
|
||||||
<div class="handle right" @mousedown.prevent="onRightHandleMousedown"></div>
|
<div :class="$style.handleRight" @mousedown.prevent="onRightHandleMousedown"></div>
|
||||||
<div class="handle bottom" @mousedown.prevent="onBottomHandleMousedown"></div>
|
<div :class="$style.handleBottom" @mousedown.prevent="onBottomHandleMousedown"></div>
|
||||||
<div class="handle left" @mousedown.prevent="onLeftHandleMousedown"></div>
|
<div :class="$style.handleLeft" @mousedown.prevent="onLeftHandleMousedown"></div>
|
||||||
<div class="handle top-left" @mousedown.prevent="onTopLeftHandleMousedown"></div>
|
<div :class="$style.handleTopLeft" @mousedown.prevent="onTopLeftHandleMousedown"></div>
|
||||||
<div class="handle top-right" @mousedown.prevent="onTopRightHandleMousedown"></div>
|
<div :class="$style.handleTopRight" @mousedown.prevent="onTopRightHandleMousedown"></div>
|
||||||
<div class="handle bottom-right" @mousedown.prevent="onBottomRightHandleMousedown"></div>
|
<div :class="$style.handleBottomRight" @mousedown.prevent="onBottomRightHandleMousedown"></div>
|
||||||
<div class="handle bottom-left" @mousedown.prevent="onBottomLeftHandleMousedown"></div>
|
<div :class="$style.handleBottomLeft" @mousedown.prevent="onBottomLeftHandleMousedown"></div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
@@ -407,166 +414,174 @@ defineExpose({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.window-enter-active, .window-leave-active {
|
.transition_window_enterActive,
|
||||||
|
.transition_window_leaveActive {
|
||||||
transition: opacity 0.2s, transform 0.2s !important;
|
transition: opacity 0.2s, transform 0.2s !important;
|
||||||
}
|
}
|
||||||
.window-enter-from, .window-leave-to {
|
.transition_window_enterFrom,
|
||||||
|
.transition_window_leaveTo {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: scale(0.9);
|
transform: scale(0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ebkgocck {
|
.root {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
||||||
> .body {
|
|
||||||
overflow: clip;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
contain: content;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: var(--radius);
|
|
||||||
|
|
||||||
> .header {
|
|
||||||
--height: 39px;
|
|
||||||
|
|
||||||
&.mini {
|
|
||||||
--height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
flex-shrink: 0;
|
|
||||||
user-select: none;
|
|
||||||
height: var(--height);
|
|
||||||
background: var(--windowHeader);
|
|
||||||
-webkit-backdrop-filter: var(--blur, blur(15px));
|
|
||||||
backdrop-filter: var(--blur, blur(15px));
|
|
||||||
//border-bottom: solid 1px var(--divider);
|
|
||||||
font-size: 95%;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
> .left, > .right {
|
|
||||||
> .button {
|
|
||||||
height: var(--height);
|
|
||||||
width: var(--height);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: var(--fgHighlighted);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.highlighted {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .left {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .right {
|
|
||||||
min-width: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .title {
|
|
||||||
flex: 1;
|
|
||||||
position: relative;
|
|
||||||
line-height: var(--height);
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
cursor: move;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .body {
|
|
||||||
flex: 1;
|
|
||||||
overflow: auto;
|
|
||||||
background: var(--panel);
|
|
||||||
container-type: inline-size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .handle {
|
|
||||||
$size: 8px;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
&.top {
|
|
||||||
top: -($size);
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: $size;
|
|
||||||
cursor: ns-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
|
||||||
top: 0;
|
|
||||||
right: -($size);
|
|
||||||
width: $size;
|
|
||||||
height: 100%;
|
|
||||||
cursor: ew-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bottom {
|
|
||||||
bottom: -($size);
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: $size;
|
|
||||||
cursor: ns-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.left {
|
|
||||||
top: 0;
|
|
||||||
left: -($size);
|
|
||||||
width: $size;
|
|
||||||
height: 100%;
|
|
||||||
cursor: ew-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.top-left {
|
|
||||||
top: -($size);
|
|
||||||
left: -($size);
|
|
||||||
width: $size * 2;
|
|
||||||
height: $size * 2;
|
|
||||||
cursor: nwse-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.top-right {
|
|
||||||
top: -($size);
|
|
||||||
right: -($size);
|
|
||||||
width: $size * 2;
|
|
||||||
height: $size * 2;
|
|
||||||
cursor: nesw-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bottom-right {
|
|
||||||
bottom: -($size);
|
|
||||||
right: -($size);
|
|
||||||
width: $size * 2;
|
|
||||||
height: $size * 2;
|
|
||||||
cursor: nwse-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bottom-left {
|
|
||||||
bottom: -($size);
|
|
||||||
left: -($size);
|
|
||||||
width: $size * 2;
|
|
||||||
height: $size * 2;
|
|
||||||
cursor: nesw-resize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.maximized {
|
&.maximized {
|
||||||
> .body {
|
> .body {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
overflow: clip;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
contain: content;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
--height: 39px;
|
||||||
|
|
||||||
|
&.mini {
|
||||||
|
--height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
user-select: none;
|
||||||
|
height: var(--height);
|
||||||
|
background: var(--windowHeader);
|
||||||
|
-webkit-backdrop-filter: var(--blur, blur(15px));
|
||||||
|
backdrop-filter: var(--blur, blur(15px));
|
||||||
|
//border-bottom: solid 1px var(--divider);
|
||||||
|
font-size: 95%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerButton {
|
||||||
|
height: var(--height);
|
||||||
|
width: var(--height);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--fgHighlighted);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.highlighted {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerLeft {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerRight {
|
||||||
|
min-width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerTitle {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
line-height: var(--height);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
background: var(--panel);
|
||||||
|
container-type: inline-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
$handleSize: 8px;
|
||||||
|
|
||||||
|
.handle {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleTop {
|
||||||
|
composes: handle;
|
||||||
|
top: -($handleSize);
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: $handleSize;
|
||||||
|
cursor: ns-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleRight {
|
||||||
|
composes: handle;
|
||||||
|
top: 0;
|
||||||
|
right: -($handleSize);
|
||||||
|
width: $handleSize;
|
||||||
|
height: 100%;
|
||||||
|
cursor: ew-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleBottom {
|
||||||
|
composes: handle;
|
||||||
|
bottom: -($handleSize);
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: $handleSize;
|
||||||
|
cursor: ns-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleLeft {
|
||||||
|
composes: handle;
|
||||||
|
top: 0;
|
||||||
|
left: -($handleSize);
|
||||||
|
width: $handleSize;
|
||||||
|
height: 100%;
|
||||||
|
cursor: ew-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleTopLeft {
|
||||||
|
composes: handle;
|
||||||
|
top: -($handleSize);
|
||||||
|
left: -($handleSize);
|
||||||
|
width: $handleSize * 2;
|
||||||
|
height: $handleSize * 2;
|
||||||
|
cursor: nwse-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleTopRight {
|
||||||
|
composes: handle;
|
||||||
|
top: -($handleSize);
|
||||||
|
right: -($handleSize);
|
||||||
|
width: $handleSize * 2;
|
||||||
|
height: $handleSize * 2;
|
||||||
|
cursor: nesw-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleBottomRight {
|
||||||
|
composes: handle;
|
||||||
|
bottom: -($handleSize);
|
||||||
|
right: -($handleSize);
|
||||||
|
width: $handleSize * 2;
|
||||||
|
height: $handleSize * 2;
|
||||||
|
cursor: nwse-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.handleBottomLeft {
|
||||||
|
composes: handle;
|
||||||
|
bottom: -($handleSize);
|
||||||
|
left: -($handleSize);
|
||||||
|
width: $handleSize * 2;
|
||||||
|
height: $handleSize * 2;
|
||||||
|
cursor: nesw-resize;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="chosen" class="qiivuoyo">
|
<div v-if="chosen" :class="$style.root">
|
||||||
<div v-if="!showMenu" class="main" :class="chosen.place">
|
<div v-if="!showMenu" :class="[$style.main, $style['form_' + chosen.place]]">
|
||||||
<a :href="chosen.url" target="_blank">
|
<a :href="chosen.url" target="_blank" :class="$style.link">
|
||||||
<img :src="chosen.imageUrl">
|
<img :src="chosen.imageUrl" :class="$style.img">
|
||||||
<button class="_button menu" @click.prevent.stop="toggleMenu"><span class="ti ti-info-circle info-circle"></span></button>
|
<button class="_button" :class="$style.i" @click.prevent.stop="toggleMenu"><i :class="$style.iIcon" class="ti ti-info-circle"></i></button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="menu">
|
<div v-else :class="$style.menu">
|
||||||
<div class="body">
|
<div :class="$style.menuContainer">
|
||||||
<div>Ads by {{ host }}</div>
|
<div>Ads by {{ host }}</div>
|
||||||
<!--<MkButton class="button" primary>{{ $ts._ad.like }}</MkButton>-->
|
<!--<MkButton class="button" primary>{{ $ts._ad.like }}</MkButton>-->
|
||||||
<MkButton v-if="chosen.ratio !== 0" class="button" @click="reduceFrequency">{{ $ts._ad.reduceFrequencyOfThisAd }}</MkButton>
|
<MkButton v-if="chosen.ratio !== 0" :class="$style.menuButton" @click="reduceFrequency">{{ $ts._ad.reduceFrequencyOfThisAd }}</MkButton>
|
||||||
<button class="_textButton" @click="toggleMenu">{{ $ts._ad.back }}</button>
|
<button class="_textButton" @click="toggleMenu">{{ $ts._ad.back }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -92,95 +92,99 @@ function reduceFrequency(): void {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.qiivuoyo {
|
.root {
|
||||||
background-size: auto auto;
|
background-size: auto auto;
|
||||||
background-image: repeating-linear-gradient(45deg, transparent, transparent 8px, var(--ad) 8px, var(--ad) 14px );
|
background-image: repeating-linear-gradient(45deg, transparent, transparent 8px, var(--ad) 8px, var(--ad) 14px );
|
||||||
|
}
|
||||||
|
|
||||||
> .main {
|
.main {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
> a {
|
&.form_square {
|
||||||
display: inline-block;
|
> .link,
|
||||||
position: relative;
|
> .link > .img {
|
||||||
vertical-align: bottom;
|
max-width: min(300px, 100%);
|
||||||
|
max-height: 300px;
|
||||||
&:hover {
|
|
||||||
> img {
|
|
||||||
filter: contrast(120%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> img {
|
|
||||||
display: block;
|
|
||||||
object-fit: contain;
|
|
||||||
margin: auto;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .menu {
|
|
||||||
position: absolute;
|
|
||||||
top: 1px;
|
|
||||||
right: 1px;
|
|
||||||
|
|
||||||
> .info-circle {
|
|
||||||
border: 3px solid var(--panel);
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--panel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.square {
|
|
||||||
> a ,
|
|
||||||
> a > img {
|
|
||||||
max-width: min(300px, 100%);
|
|
||||||
max-height: 300px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.horizontal {
|
|
||||||
padding: 8px;
|
|
||||||
|
|
||||||
> a ,
|
|
||||||
> a > img {
|
|
||||||
max-width: min(600px, 100%);
|
|
||||||
max-height: 80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.horizontal-big {
|
|
||||||
padding: 8px;
|
|
||||||
|
|
||||||
> a ,
|
|
||||||
> a > img {
|
|
||||||
max-width: min(600px, 100%);
|
|
||||||
max-height: 250px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.vertical {
|
|
||||||
> a ,
|
|
||||||
> a > img {
|
|
||||||
max-width: min(100px, 100%);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .menu {
|
&.form_horizontal {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
> .body {
|
> .link,
|
||||||
padding: 8px;
|
> .link > .img {
|
||||||
margin: 0 auto;
|
max-width: min(600px, 100%);
|
||||||
max-width: 400px;
|
max-height: 80px;
|
||||||
border: solid 1px var(--divider);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .button {
|
&.form_horizontal-big {
|
||||||
margin: 8px auto;
|
padding: 8px;
|
||||||
}
|
|
||||||
|
> .link,
|
||||||
|
> .link > .img {
|
||||||
|
max-width: min(600px, 100%);
|
||||||
|
max-height: 250px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.form_vertical {
|
||||||
|
> .link,
|
||||||
|
> .link > .img {
|
||||||
|
max-width: min(100px, 100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: bottom;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
> .img {
|
||||||
|
filter: contrast(120%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.img {
|
||||||
|
display: block;
|
||||||
|
object-fit: contain;
|
||||||
|
margin: auto;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.i {
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
right: 1px;
|
||||||
|
display: grid;
|
||||||
|
place-content: center;
|
||||||
|
background: var(--panel);
|
||||||
|
border-radius: 100%;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iIcon {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
padding: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuContainer {
|
||||||
|
padding: 8px;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 400px;
|
||||||
|
border: solid 1px var(--divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuButton {
|
||||||
|
margin: 8px auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,28 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="mk-ellipsis">
|
<span :class="$style.root">
|
||||||
<span>.</span><span>.</span><span>.</span>
|
<span :class="$style.dot">.</span><span :class="$style.dot">.</span><span :class="$style.dot">.</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.mk-ellipsis {
|
|
||||||
> span {
|
|
||||||
animation: ellipsis 1.4s infinite ease-in-out both;
|
|
||||||
|
|
||||||
&:nth-child(1) {
|
|
||||||
animation-delay: 0s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
animation-delay: 0.16s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3) {
|
|
||||||
animation-delay: 0.32s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes ellipsis {
|
@keyframes ellipsis {
|
||||||
0%, 80%, 100% {
|
0%, 80%, 100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@@ -31,4 +13,24 @@
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.root {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
animation: ellipsis 1.4s infinite ease-in-out both;
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
animation-delay: 0.16s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
animation-delay: 0.32s;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<Transition :name="$store.state.animation ? '_transition_zoom' : ''" appear>
|
<Transition :name="$store.state.animation ? '_transition_zoom' : ''" appear>
|
||||||
<div class="mjndxjcg">
|
<div :class="$style.root">
|
||||||
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
|
<img :class="$style.img" src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
|
||||||
<p><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
|
<p :class="$style.text"><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
|
||||||
<MkButton class="button" @click="() => $emit('retry')">{{ i18n.ts.retry }}</MkButton>
|
<MkButton :class="$style.button" @click="() => $emit('retry')">{{ i18n.ts.retry }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</template>
|
</template>
|
||||||
@@ -13,24 +13,24 @@ import MkButton from '@/components/MkButton.vue';
|
|||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.mjndxjcg {
|
.root {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
> p {
|
.text {
|
||||||
margin: 0 0 8px 0;
|
margin: 0 0 8px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .button {
|
.button {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
> img {
|
.img {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
height: 128px;
|
height: 128px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<MfmCore :text="text" :plain="plain" :nowrap="nowrap" :author="author" :is-note="isNote" class="havbbuyv" :class="{ nowrap }"/>
|
<MfmCore :text="text" :plain="plain" :nowrap="nowrap" :author="author" :is-note="isNote" :class="[$style.root, { [$style.nowrap]: nowrap }]"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -157,8 +157,8 @@ const props = withDefaults(defineProps<{
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.havbbuyv {
|
.root {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
|
||||||
&.nowrap {
|
&.nowrap {
|
||||||
@@ -167,24 +167,5 @@ const props = withDefaults(defineProps<{
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.quote) {
|
|
||||||
display: block;
|
|
||||||
margin: 8px;
|
|
||||||
padding: 6px 0 6px 12px;
|
|
||||||
color: var(--fg);
|
|
||||||
border-left: solid 3px var(--fg);
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(pre) {
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
> ::v-deep(code) {
|
|
||||||
font-size: 0.8em;
|
|
||||||
word-break: break-all;
|
|
||||||
padding: 4px 6px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,36 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="show" ref="el" class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick">
|
<div v-if="show" ref="el" :class="[$style.root, { [$style.slim]: narrow, [$style.thin]: thin_ }]" :style="{ background: bg }" @click="onClick">
|
||||||
<div v-if="narrow" class="buttons left">
|
<div v-if="narrow" :class="$style.buttonsLeft">
|
||||||
<MkAvatar v-if="props.displayMyAvatar && $i" class="avatar" :user="$i" :disable-preview="true"/>
|
<MkAvatar v-if="props.displayMyAvatar && $i" :class="$style.avatar" :user="$i" :disable-preview="true"/>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="metadata">
|
<template v-if="metadata">
|
||||||
<div v-if="!hideTitle" class="titleContainer" @click="showTabsPopup">
|
<div v-if="!hideTitle" :class="$style.titleContainer" @click="showTabsPopup">
|
||||||
<MkAvatar v-if="metadata.avatar" class="avatar" :user="metadata.avatar" :disable-preview="true" :show-indicator="true"/>
|
<MkAvatar v-if="metadata.avatar" :class="$style.titleAvatar" :user="metadata.avatar" :disable-preview="true" :show-indicator="true"/>
|
||||||
<i v-else-if="metadata.icon" class="icon" :class="metadata.icon"></i>
|
<i v-else-if="metadata.icon" :class="[$style.titleIcon, metadata.icon]"></i>
|
||||||
|
|
||||||
<div class="title">
|
<div :class="$style.title">
|
||||||
<MkUserName v-if="metadata.userName" :user="metadata.userName" :nowrap="true" class="title"/>
|
<MkUserName v-if="metadata.userName" :user="metadata.userName" :nowrap="true"/>
|
||||||
<div v-else-if="metadata.title" class="title">{{ metadata.title }}</div>
|
<div v-else-if="metadata.title">{{ metadata.title }}</div>
|
||||||
<div v-if="!narrow && metadata.subtitle" class="subtitle">
|
<div v-if="!narrow && metadata.subtitle" :class="$style.subtitle">
|
||||||
{{ metadata.subtitle }}
|
{{ metadata.subtitle }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="narrow && hasTabs" class="subtitle activeTab">
|
<div v-if="narrow && hasTabs" :class="[$style.subtitle, $style.activeTab]">
|
||||||
{{ tabs.find(tab => tab.key === props.tab)?.title }}
|
{{ tabs.find(tab => tab.key === props.tab)?.title }}
|
||||||
<i class="chevron ti ti-chevron-down"></i>
|
<i class="ti ti-chevron-down" :class="$style.chevron"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!narrow || hideTitle" class="tabs">
|
<div v-if="!narrow || hideTitle" :class="$style.tabs">
|
||||||
<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = (el as HTMLElement)" v-tooltip.noDelay="tab.title" class="tab _button" :class="{ active: tab.key != null && tab.key === props.tab }" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
|
<button v-for="tab in tabs" :ref="(el) => tabRefs[tab.key] = (el as HTMLElement)" v-tooltip.noDelay="tab.title" class="_button" :class="[$style.tab, { [$style.active]: tab.key != null && tab.key === props.tab }]" @mousedown="(ev) => onTabMousedown(tab, ev)" @click="(ev) => onTabClick(tab, ev)">
|
||||||
<i v-if="tab.icon" class="icon" :class="tab.icon"></i>
|
<i v-if="tab.icon" :class="[$style.tabIcon, tab.icon]"></i>
|
||||||
<span v-if="!tab.iconOnly" class="title">{{ tab.title }}</span>
|
<span v-if="!tab.iconOnly" :class="$style.tabTitle">{{ tab.title }}</span>
|
||||||
</button>
|
</button>
|
||||||
<div ref="tabHighlightEl" class="highlight"></div>
|
<div ref="tabHighlightEl" :class="$style.tabHighlight"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="buttons right">
|
<div :class="$style.buttonsRight">
|
||||||
<template v-for="action in actions">
|
<template v-for="action in actions">
|
||||||
<button v-tooltip.noDelay="action.text" class="_button button" :class="{ highlighted: action.highlighted }" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
<button v-tooltip.noDelay="action.text" class="_button" :class="[$style.button, { [$style.highlighted]: action.highlighted }]" @click.stop="action.handler" @touchstart="preventDrag"><i :class="action.icon"></i></button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -178,8 +178,8 @@ onUnmounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.fdidabkb {
|
.root {
|
||||||
--height: 50px;
|
--height: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -215,154 +215,156 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .buttons {
|
.buttons {
|
||||||
--margin: 8px;
|
--margin: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: var(--height);
|
min-width: var(--height);
|
||||||
height: var(--height);
|
height: var(--height);
|
||||||
margin: 0 var(--margin);
|
margin: 0 var(--margin);
|
||||||
|
|
||||||
&.left {
|
&:empty {
|
||||||
margin-right: auto;
|
width: var(--height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .avatar {
|
.buttonsLeft {
|
||||||
$size: 32px;
|
composes: buttons;
|
||||||
display: inline-block;
|
margin-right: auto;
|
||||||
width: $size;
|
}
|
||||||
height: $size;
|
|
||||||
vertical-align: bottom;
|
|
||||||
margin: 0 8px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.right {
|
.buttonsRight {
|
||||||
margin-left: auto;
|
composes: buttons;
|
||||||
}
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
&:empty {
|
.avatar {
|
||||||
width: var(--height);
|
$size: 32px;
|
||||||
}
|
display: inline-block;
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
vertical-align: bottom;
|
||||||
|
margin: 0 8px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
> .button {
|
.button {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: calc(var(--height) - (var(--margin) * 2));
|
height: calc(var(--height) - (var(--margin) * 2));
|
||||||
width: calc(var(--height) - (var(--margin) * 2));
|
width: calc(var(--height) - (var(--margin) * 2));
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba(0, 0, 0, 0.05);
|
background: rgba(0, 0, 0, 0.05);
|
||||||
}
|
|
||||||
|
|
||||||
&.highlighted {
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .fullButton {
|
|
||||||
& + .fullButton {
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> .titleContainer {
|
&.highlighted {
|
||||||
display: flex;
|
color: var(--accent);
|
||||||
align-items: center;
|
|
||||||
max-width: 400px;
|
|
||||||
overflow: auto;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: bold;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-left: 24px;
|
|
||||||
|
|
||||||
> .avatar {
|
|
||||||
$size: 32px;
|
|
||||||
display: inline-block;
|
|
||||||
width: $size;
|
|
||||||
height: $size;
|
|
||||||
vertical-align: bottom;
|
|
||||||
margin: 0 8px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .icon {
|
|
||||||
margin-right: 8px;
|
|
||||||
width: 16px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .title {
|
|
||||||
min-width: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
line-height: 1.1;
|
|
||||||
|
|
||||||
> .subtitle {
|
|
||||||
opacity: 0.6;
|
|
||||||
font-size: 0.8em;
|
|
||||||
font-weight: normal;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
&.activeTab {
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
> .chevron {
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .tabs {
|
.fullButton {
|
||||||
position: relative;
|
& + .fullButton {
|
||||||
margin-left: 16px;
|
margin-left: 12px;
|
||||||
font-size: 0.8em;
|
}
|
||||||
overflow: auto;
|
}
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
> .tab {
|
.titleContainer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 400px;
|
||||||
|
overflow: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titleAvatar {
|
||||||
|
$size: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
vertical-align: bottom;
|
||||||
|
margin: 0 8px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titleIcon {
|
||||||
|
margin-right: 8px;
|
||||||
|
width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
opacity: 0.6;
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-weight: normal;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
&.activeTab {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
> .chevron {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
margin-left: 6px;
|
||||||
padding: 0 10px;
|
|
||||||
height: 100%;
|
|
||||||
font-weight: normal;
|
|
||||||
opacity: 0.7;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .icon + .title {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .highlight {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
height: 3px;
|
|
||||||
background: var(--accent);
|
|
||||||
border-radius: 999px;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
position: relative;
|
||||||
|
margin-left: 16px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
overflow: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 10px;
|
||||||
|
height: 100%;
|
||||||
|
font-weight: normal;
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabIcon + .tabTitle {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabHighlight {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
height: 3px;
|
||||||
|
background: var(--accent);
|
||||||
|
border-radius: 999px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -12,6 +12,15 @@ import MkA from '@/components/global/MkA.vue';
|
|||||||
import { host } from '@/config';
|
import { host } from '@/config';
|
||||||
import { MFM_TAGS } from '@/scripts/mfm-tags';
|
import { MFM_TAGS } from '@/scripts/mfm-tags';
|
||||||
|
|
||||||
|
const QUOTE_STYLE = `
|
||||||
|
display: block;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 6px 0 6px 12px;
|
||||||
|
color: var(--fg);
|
||||||
|
border-left: solid 3px var(--fg);
|
||||||
|
opacity: 0.7;
|
||||||
|
`.split('\n').join(' ');
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
text: {
|
text: {
|
||||||
@@ -276,11 +285,11 @@ export default defineComponent({
|
|||||||
case 'quote': {
|
case 'quote': {
|
||||||
if (!this.nowrap) {
|
if (!this.nowrap) {
|
||||||
return [h('div', {
|
return [h('div', {
|
||||||
class: 'quote',
|
style: QUOTE_STYLE,
|
||||||
}, genEl(token.children))];
|
}, genEl(token.children))];
|
||||||
} else {
|
} else {
|
||||||
return [h('span', {
|
return [h('span', {
|
||||||
class: 'quote',
|
style: QUOTE_STYLE,
|
||||||
}, genEl(token.children))];
|
}, genEl(token.children))];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -140,6 +140,18 @@
|
|||||||
</MkInput>
|
</MkInput>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>{{ i18n.ts._role._options.webhookMax }}</template>
|
||||||
|
<template #suffix>{{ options_webhookLimit_useDefault ? i18n.ts._role.useBaseValue : (options_webhookLimit_value) }}</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSwitch v-model="options_webhookLimit_useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkInput v-model="options_webhookLimit_value" :disabled="options_webhookLimit_useDefault" type="number" :readonly="readonly">
|
||||||
|
</MkInput>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
</div>
|
</div>
|
||||||
</FormSlot>
|
</FormSlot>
|
||||||
|
|
||||||
@@ -209,6 +221,8 @@ let options_antennaLimit_useDefault = $ref(role?.options?.antennaLimit?.useDefau
|
|||||||
let options_antennaLimit_value = $ref(role?.options?.antennaLimit?.value ?? 0);
|
let options_antennaLimit_value = $ref(role?.options?.antennaLimit?.value ?? 0);
|
||||||
let options_wordMuteLimit_useDefault = $ref(role?.options?.wordMuteLimit?.useDefault ?? true);
|
let options_wordMuteLimit_useDefault = $ref(role?.options?.wordMuteLimit?.useDefault ?? true);
|
||||||
let options_wordMuteLimit_value = $ref(role?.options?.wordMuteLimit?.value ?? 0);
|
let options_wordMuteLimit_value = $ref(role?.options?.wordMuteLimit?.value ?? 0);
|
||||||
|
let options_webhookLimit_useDefault = $ref(role?.options?.webhookLimit?.useDefault ?? true);
|
||||||
|
let options_webhookLimit_value = $ref(role?.options?.webhookLimit?.value ?? 0);
|
||||||
|
|
||||||
if (_DEV_) {
|
if (_DEV_) {
|
||||||
watch($$(condFormula), () => {
|
watch($$(condFormula), () => {
|
||||||
@@ -226,6 +240,7 @@ function getOptions() {
|
|||||||
driveCapacityMb: { useDefault: options_driveCapacityMb_useDefault, value: options_driveCapacityMb_value },
|
driveCapacityMb: { useDefault: options_driveCapacityMb_useDefault, value: options_driveCapacityMb_value },
|
||||||
antennaLimit: { useDefault: options_antennaLimit_useDefault, value: options_antennaLimit_value },
|
antennaLimit: { useDefault: options_antennaLimit_useDefault, value: options_antennaLimit_value },
|
||||||
wordMuteLimit: { useDefault: options_wordMuteLimit_useDefault, value: options_wordMuteLimit_value },
|
wordMuteLimit: { useDefault: options_wordMuteLimit_useDefault, value: options_wordMuteLimit_value },
|
||||||
|
webhookLimit: { useDefault: options_webhookLimit_useDefault, value: options_webhookLimit_value },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,6 +71,13 @@
|
|||||||
</MkInput>
|
</MkInput>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>{{ i18n.ts._role._options.webhookMax }}</template>
|
||||||
|
<template #suffix>{{ options_webhookLimit }}</template>
|
||||||
|
<MkInput v-model="options_webhookLimit" type="number">
|
||||||
|
</MkInput>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkButton primary rounded @click="updateBaseRole">{{ i18n.ts.save }}</MkButton>
|
<MkButton primary rounded @click="updateBaseRole">{{ i18n.ts.save }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
@@ -111,6 +118,7 @@ let options_canManageCustomEmojis = $ref(instance.baseRole.canManageCustomEmojis
|
|||||||
let options_driveCapacityMb = $ref(instance.baseRole.driveCapacityMb);
|
let options_driveCapacityMb = $ref(instance.baseRole.driveCapacityMb);
|
||||||
let options_antennaLimit = $ref(instance.baseRole.antennaLimit);
|
let options_antennaLimit = $ref(instance.baseRole.antennaLimit);
|
||||||
let options_wordMuteLimit = $ref(instance.baseRole.wordMuteLimit);
|
let options_wordMuteLimit = $ref(instance.baseRole.wordMuteLimit);
|
||||||
|
let options_webhookLimit = $ref(instance.baseRole.webhookLimit);
|
||||||
|
|
||||||
async function updateBaseRole() {
|
async function updateBaseRole() {
|
||||||
await os.apiWithDialog('admin/roles/update-default-role-override', {
|
await os.apiWithDialog('admin/roles/update-default-role-override', {
|
||||||
@@ -123,6 +131,7 @@ async function updateBaseRole() {
|
|||||||
driveCapacityMb: options_driveCapacityMb,
|
driveCapacityMb: options_driveCapacityMb,
|
||||||
antennaLimit: options_antennaLimit,
|
antennaLimit: options_antennaLimit,
|
||||||
wordMuteLimit: options_wordMuteLimit,
|
wordMuteLimit: options_wordMuteLimit,
|
||||||
|
webhookLimit: options_webhookLimit,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,8 @@
|
|||||||
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
|
||||||
<div :class="$style.tl">
|
<div :class="$style.tl">
|
||||||
<XTimeline
|
<XTimeline
|
||||||
ref="tl" :key="src"
|
ref="tlComponent"
|
||||||
|
:key="src"
|
||||||
:src="src"
|
:src="src"
|
||||||
:sound="true"
|
:sound="true"
|
||||||
@queue="queueUpdated"
|
@queue="queueUpdated"
|
||||||
|
@@ -65,6 +65,3 @@ defineExpose({
|
|||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
</style>
|
|
||||||
|
@@ -53,6 +53,3 @@ const menu = [{
|
|||||||
action: setList,
|
action: setList,
|
||||||
}];
|
}];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
</style>
|
|
||||||
|
@@ -8,12 +8,12 @@
|
|||||||
<span style="margin-left: 8px;">{{ column.name }}</span>
|
<span style="margin-left: 8px;">{{ column.name }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div v-if="disabled" class="iwaalbte">
|
<div v-if="disabled" :class="$style.disabled">
|
||||||
<p>
|
<p :class="$style.disabledTitle">
|
||||||
<i class="ti ti-minus-circle"></i>
|
<i class="ti ti-minus-circle"></i>
|
||||||
{{ $t('disabled-timeline.title') }}
|
{{ $t('disabled-timeline.title') }}
|
||||||
</p>
|
</p>
|
||||||
<p class="desc">{{ $t('disabled-timeline.description') }}</p>
|
<p :class="$style.disabledDescription">{{ $t('disabled-timeline.description') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<XTimeline v-else-if="column.tl" ref="timeline" :key="column.tl" :src="column.tl" @after="() => emit('loaded')"/>
|
<XTimeline v-else-if="column.tl" ref="timeline" :key="column.tl" :src="column.tl" @after="() => emit('loaded')"/>
|
||||||
</XColumn>
|
</XColumn>
|
||||||
@@ -80,16 +80,16 @@ const menu = [{
|
|||||||
}];
|
}];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.iwaalbte {
|
.disabled {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
> p {
|
.disabledTitle {
|
||||||
margin: 16px;
|
margin: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
&.desc {
|
.disabledDescription {
|
||||||
font-size: 14px;
|
font-size: 90%;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
<XColumn :menu="menu" :naked="true" :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)">
|
<XColumn :menu="menu" :naked="true" :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)">
|
||||||
<template #header><i class="ti ti-apps" style="margin-right: 8px;"></i>{{ column.name }}</template>
|
<template #header><i class="ti ti-apps" style="margin-right: 8px;"></i>{{ column.name }}</template>
|
||||||
|
|
||||||
<div class="wtdtxvec">
|
<div :class="$style.root">
|
||||||
<div v-if="!(column.widgets && column.widgets.length > 0) && !edit" class="intro">{{ i18n.ts._deck.widgetsIntroduction }}</div>
|
<div v-if="!(column.widgets && column.widgets.length > 0) && !edit" :class="$style.intro">{{ i18n.ts._deck.widgetsIntroduction }}</div>
|
||||||
<XWidgets :edit="edit" :widgets="column.widgets ?? []" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="edit = false"/>
|
<XWidgets :edit="edit" :widgets="column.widgets ?? []" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="edit = false"/>
|
||||||
</div>
|
</div>
|
||||||
</XColumn>
|
</XColumn>
|
||||||
@@ -54,16 +54,16 @@ const menu = [{
|
|||||||
}];
|
}];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" module>
|
||||||
.wtdtxvec {
|
.root {
|
||||||
--margin: 8px;
|
--margin: 8px;
|
||||||
--panelBorder: none;
|
--panelBorder: none;
|
||||||
|
|
||||||
padding: 0 var(--margin);
|
padding: 0 var(--margin);
|
||||||
|
}
|
||||||
|
|
||||||
> .intro {
|
.intro {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import path from 'path';
|
||||||
import pluginVue from '@vitejs/plugin-vue';
|
import pluginVue from '@vitejs/plugin-vue';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
@@ -62,7 +63,8 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
return 'x' + toBase62(hash(`${filename} ${name}`)).substring(0, 4);
|
return 'x' + toBase62(hash(`${filename} ${name}`)).substring(0, 4);
|
||||||
} else {
|
} else {
|
||||||
return 'x' + toBase62(hash(`${filename} ${name}`)).substring(0, 4) + '-' + name;
|
//return 'x' + toBase62(hash(`${filename} ${name}`)).substring(0, 4) + '-' + name;
|
||||||
|
return (path.relative(__dirname, filename.split('?')[0]) + '-' + name).replace(/[\\\/\.\?&=]/g, '-').replace(/(src-|vue-)/g, '');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user