This commit is contained in:
syuilo
2020-12-26 10:47:36 +09:00
parent 9d81d06853
commit 5a8cc7851b
200 changed files with 1562 additions and 1533 deletions

View File

@ -2,7 +2,7 @@
<XWindow ref="window" :initial-width="400" :initial-height="500" :can-resize="true" @closed="$emit('closed')">
<template #header>
<Fa :icon="faExclamationCircle" style="margin-right: 0.5em;"/>
<I18n src="reportAbuseOf" tag="span">
<I18n :src="$ts.reportAbuseOf" tag="span">
<template #name>
<b><MkAcct :user="user"/></b>
</template>
@ -12,14 +12,14 @@
<div class="_section">
<div class="_content">
<MkTextarea v-model:value="comment">
<span>{{ $t('details') }}</span>
<template #desc>{{ $t('fillAbuseReportDescription') }}</template>
<span>{{ $ts.details }}</span>
<template #desc>{{ $ts.fillAbuseReportDescription }}</template>
</MkTextarea>
</div>
</div>
<div class="_section">
<div class="_content">
<MkButton @click="send" primary full :disabled="comment.length === 0">{{ $t('send') }}</MkButton>
<MkButton @click="send" primary full :disabled="comment.length === 0">{{ $ts.send }}</MkButton>
</div>
</div>
</div>
@ -69,7 +69,7 @@ export default defineComponent({
}, undefined, res => {
os.dialog({
type: 'success',
text: this.$t('abuseReported')
text: this.$ts.abuseReported
});
this.$refs.window.close();
});

View File

@ -8,7 +8,7 @@
</span>
<span class="username">@{{ acct(user) }}</span>
</li>
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">{{ $t('selectUser') }}</li>
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">{{ $ts.selectUser }}</li>
</ol>
<ol class="hashtags" ref="suggests" v-if="hashtags.length > 0">
<li v-for="hashtag in hashtags" @click="complete(type, hashtag)" @keydown="onKeydown" tabindex="-1">

View File

@ -1,6 +1,6 @@
<template>
<div>
<span v-if="!available">{{ $t('waiting') }}<MkEllipsis/></span>
<span v-if="!available">{{ $ts.waiting }}<MkEllipsis/></span>
<div ref="captcha"></div>
</div>
</template>

View File

@ -6,14 +6,14 @@
>
<template v-if="!wait">
<template v-if="isFollowing">
<span v-if="full">{{ $t('unfollow') }}</span><Fa :icon="faMinus"/>
<span v-if="full">{{ $ts.unfollow }}</span><Fa :icon="faMinus"/>
</template>
<template v-else>
<span v-if="full">{{ $t('follow') }}</span><Fa :icon="faPlus"/>
<span v-if="full">{{ $ts.follow }}</span><Fa :icon="faPlus"/>
</template>
</template>
<template v-else>
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse fixed-width/>
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse fixed-width/>
</template>
</button>
</template>

View File

@ -6,7 +6,7 @@
<div class="status">
<div>
<Fa :icon="faUsers" fixed-width/>
<I18n src="_channel.usersCount" tag="span" style="margin-left: 4px;">
<I18n :src="$ts._channel.usersCount" tag="span" style="margin-left: 4px;">
<template #n>
<b>{{ channel.usersCount }}</b>
</template>
@ -14,7 +14,7 @@
</div>
<div>
<Fa :icon="faPencilAlt" fixed-width/>
<I18n src="_channel.notesCount" tag="span" style="margin-left: 4px;">
<I18n :src="$ts._channel.notesCount" tag="span" style="margin-left: 4px;">
<template #n>
<b>{{ channel.notesCount }}</b>
</template>
@ -27,7 +27,7 @@
</article>
<footer>
<span v-if="channel.lastNotedAt">
{{ $t('updatedAt') }}: <MkTime :time="channel.lastNotedAt"/>
{{ $ts.updatedAt }}: <MkTime :time="channel.lastNotedAt"/>
</span>
</footer>
</MkA>

View File

@ -1,6 +1,6 @@
<template>
<button class="nrvgflfu _button" @click="toggle">
<b>{{ value ? $t('_cw.hide') : $t('_cw.show') }}</b>
<b>{{ value ? $ts._cw.hide : $ts._cw.show }}</b>
<span v-if="!value">{{ label }}</span>
</button>
</template>
@ -27,7 +27,7 @@ export default defineComponent({
return concat([
this.note.text ? [this.$t('_cw.chars', { count: length(this.note.text) })] : [],
this.note.files && this.note.files.length !== 0 ? [this.$t('_cw.files', { count: this.note.files.length }) ] : [],
this.note.poll != null ? [this.$t('poll')] : []
this.note.poll != null ? [this.$ts.poll] : []
] as string[][]).join(' / ');
}
},

View File

@ -26,8 +26,8 @@
</template>
</MkSelect>
<div class="buttons" v-if="(showOkButton || showCancelButton) && !actions">
<MkButton inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select">{{ (showCancelButton || input || select) ? $t('ok') : $t('gotIt') }}</MkButton>
<MkButton inline @click="cancel" v-if="showCancelButton || input || select">{{ $t('cancel') }}</MkButton>
<MkButton inline @click="ok" v-if="showOkButton" primary :autofocus="!input && !select">{{ (showCancelButton || input || select) ? $ts.ok : $ts.gotIt }}</MkButton>
<MkButton inline @click="cancel" v-if="showCancelButton || input || select">{{ $ts.cancel }}</MkButton>
</div>
<div class="buttons" v-if="actions">
<MkButton v-for="action in actions" inline @click="() => { action.callback(); close(); }" :primary="action.primary" :key="action.text">{{ action.text }}</MkButton>

View File

@ -10,7 +10,7 @@
@closed="$emit('closed')"
>
<template #header>
{{ multiple ? ((type === 'file') ? $t('selectFiles') : $t('selectFolders')) : ((type === 'file') ? $t('selectFile') : $t('selectFolder')) }}
{{ multiple ? ((type === 'file') ? $ts.selectFiles : $ts.selectFolders) : ((type === 'file') ? $ts.selectFile : $ts.selectFolder) }}
<span v-if="selected.length > 0" style="margin-left: 8px; opacity: 0.5;">({{ number(selected.length) }})</span>
</template>
<XDrive :multiple="multiple" @changeSelection="onChangeSelection" @selected="ok()" :select="type"/>

View File

@ -6,7 +6,7 @@
@closed="$emit('closed')"
>
<template #header>
{{ $t('drive') }}
{{ $ts.drive }}
</template>
<XDrive :initial-folder="initialFolder"/>
</XWindow>

View File

@ -10,15 +10,15 @@
>
<div class="label" v-if="$i.avatarId == file.id">
<img src="/assets/label.svg"/>
<p>{{ $t('avatar') }}</p>
<p>{{ $ts.avatar }}</p>
</div>
<div class="label" v-if="$i.bannerId == file.id">
<img src="/assets/label.svg"/>
<p>{{ $t('banner') }}</p>
<p>{{ $ts.banner }}</p>
</div>
<div class="label red" v-if="file.isSensitive">
<img src="/assets/label-red.svg"/>
<p>{{ $t('nsfw') }}</p>
<p>{{ $ts.nsfw }}</p>
</div>
<MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain"/>
@ -82,26 +82,26 @@ export default defineComponent({
methods: {
getMenu() {
return [{
text: this.$t('rename'),
text: this.$ts.rename,
icon: faICursor,
action: this.rename
}, {
text: this.file.isSensitive ? this.$t('unmarkAsSensitive') : this.$t('markAsSensitive'),
text: this.file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive,
icon: this.file.isSensitive ? faEye : faEyeSlash,
action: this.toggleSensitive
}, null, {
text: this.$t('copyUrl'),
text: this.$ts.copyUrl,
icon: faLink,
action: this.copyUrl
}, {
type: 'a',
href: this.file.url,
target: '_blank',
text: this.$t('download'),
text: this.$ts.download,
icon: faDownload,
download: this.file.name
}, null, {
text: this.$t('delete'),
text: this.$ts.delete,
icon: faTrashAlt,
danger: true,
action: this.deleteFile
@ -137,9 +137,9 @@ export default defineComponent({
rename() {
os.dialog({
title: this.$t('renameFile'),
title: this.$ts.renameFile,
input: {
placeholder: this.$t('inputNewFileName'),
placeholder: this.$ts.inputNewFileName,
default: this.file.name,
allowEmpty: false
}

View File

@ -20,7 +20,7 @@
{{ folder.name }}
</p>
<p class="upload" v-if="$store.state.uploadFolder == folder.id">
{{ $t('uploadFolder') }}
{{ $ts.uploadFolder }}
</p>
<button v-if="selectMode" class="checkbox _button" :class="{ checked: isSelected }" @click.prevent.stop="checkboxClicked"></button>
</div>
@ -155,14 +155,14 @@ export default defineComponent({
switch (err) {
case 'detected-circular-definition':
os.dialog({
title: this.$t('unableToProcess'),
text: this.$t('circularReferenceFolder')
title: this.$ts.unableToProcess,
text: this.$ts.circularReferenceFolder
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('somethingHappened')
text: this.$ts.somethingHappened
});
}
});
@ -195,9 +195,9 @@ export default defineComponent({
rename() {
os.dialog({
title: this.$t('renameFolder'),
title: this.$ts.renameFolder,
input: {
placeholder: this.$t('inputNewFolderName'),
placeholder: this.$ts.inputNewFolderName,
default: this.folder.name
}
}).then(({ canceled, result: name }) => {
@ -221,14 +221,14 @@ export default defineComponent({
case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
os.dialog({
type: 'error',
title: this.$t('unableToDelete'),
text: this.$t('hasChildFilesOrFolders')
title: this.$ts.unableToDelete,
text: this.$ts.hasChildFilesOrFolders
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('unableToDelete')
text: this.$ts.unableToDelete
});
}
});
@ -240,7 +240,7 @@ export default defineComponent({
onContextmenu(e) {
os.contextMenu([{
text: this.$t('openInWindow'),
text: this.$ts.openInWindow,
icon: faWindowRestore,
action: () => {
os.popup(import('./drive-window.vue'), {
@ -249,11 +249,11 @@ export default defineComponent({
}, 'closed');
}
}, null, {
text: this.$t('rename'),
text: this.$ts.rename,
icon: faICursor,
action: this.rename
}, null, {
text: this.$t('delete'),
text: this.$ts.delete,
icon: faTrashAlt,
danger: true,
action: this.deleteFolder

View File

@ -8,7 +8,7 @@
@drop.stop="onDrop"
>
<i v-if="folder == null"><Fa :icon="faCloud"/></i>
<span>{{ folder == null ? $t('drive') : folder.name }}</span>
<span>{{ folder == null ? $ts.drive : folder.name }}</span>
</div>
</template>

View File

@ -24,18 +24,18 @@
<XFolder v-for="f in folders" :key="f.id" class="folder" :folder="f" :select-mode="select === 'folder'" :is-selected="selectedFolders.some(x => x.id === f.id)" @chosen="chooseFolder"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="(n, i) in 16" :key="i"></div>
<MkButton ref="moreFolders" v-if="moreFolders">{{ $t('loadMore') }}</MkButton>
<MkButton ref="moreFolders" v-if="moreFolders">{{ $ts.loadMore }}</MkButton>
</div>
<div class="files" ref="filesContainer" v-show="files.length > 0">
<XFile v-for="file in files" :key="file.id" class="file" :file="file" :select-mode="select === 'file'" :is-selected="selectedFiles.some(x => x.id === file.id)" @chosen="chooseFile"/>
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div class="padding" v-for="(n, i) in 16" :key="i"></div>
<MkButton ref="loadMoreFiles" @click="fetchMoreFiles" v-show="moreFiles">{{ $t('loadMore') }}</MkButton>
<MkButton ref="loadMoreFiles" @click="fetchMoreFiles" v-show="moreFiles">{{ $ts.loadMore }}</MkButton>
</div>
<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
<p v-if="draghover">{{ $t('empty-draghover') }}</p>
<p v-if="!draghover && folder == null"><strong>{{ $t('emptyDrive') }}</strong><br/>{{ $t('empty-drive-description') }}</p>
<p v-if="!draghover && folder != null">{{ $t('emptyFolder') }}</p>
<p v-if="!draghover && folder == null"><strong>{{ $ts.emptyDrive }}</strong><br/>{{ $t('empty-drive-description') }}</p>
<p v-if="!draghover && folder != null">{{ $ts.emptyFolder }}</p>
</div>
</div>
<MkLoading v-if="fetching"/>
@ -277,14 +277,14 @@ export default defineComponent({
switch (err) {
case 'detected-circular-definition':
os.dialog({
title: this.$t('unableToProcess'),
text: this.$t('circularReferenceFolder')
title: this.$ts.unableToProcess,
text: this.$ts.circularReferenceFolder
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('somethingHappened')
text: this.$ts.somethingHappened
});
}
});
@ -298,9 +298,9 @@ export default defineComponent({
urlUpload() {
os.dialog({
title: this.$t('uploadFromUrl'),
title: this.$ts.uploadFromUrl,
input: {
placeholder: this.$t('uploadFromUrlDescription')
placeholder: this.$ts.uploadFromUrlDescription
}
}).then(({ canceled, result: url }) => {
if (canceled) return;
@ -310,17 +310,17 @@ export default defineComponent({
});
os.dialog({
title: this.$t('uploadFromUrlRequested'),
text: this.$t('uploadFromUrlMayTakeTime')
title: this.$ts.uploadFromUrlRequested,
text: this.$ts.uploadFromUrlMayTakeTime
});
});
},
createFolder() {
os.dialog({
title: this.$t('createFolder'),
title: this.$ts.createFolder,
input: {
placeholder: this.$t('folderName')
placeholder: this.$ts.folderName
}
}).then(({ canceled, result: name }) => {
if (canceled) return;
@ -335,9 +335,9 @@ export default defineComponent({
renameFolder(folder) {
os.dialog({
title: this.$t('renameFolder'),
title: this.$ts.renameFolder,
input: {
placeholder: this.$t('inputNewFolderName'),
placeholder: this.$ts.inputNewFolderName,
default: folder.name
}
}).then(({ canceled, result: name }) => {
@ -363,14 +363,14 @@ export default defineComponent({
case 'b0fc8a17-963c-405d-bfbc-859a487295e1':
os.dialog({
type: 'error',
title: this.$t('unableToDelete'),
text: this.$t('hasChildFilesOrFolders')
title: this.$ts.unableToDelete,
text: this.$ts.hasChildFilesOrFolders
});
break;
default:
os.dialog({
type: 'error',
text: this.$t('unableToDelete')
text: this.$ts.unableToDelete
});
}
});
@ -602,29 +602,29 @@ export default defineComponent({
getMenu() {
return [{
text: this.$t('addFile'),
text: this.$ts.addFile,
type: 'label'
}, {
text: this.$t('upload'),
text: this.$ts.upload,
icon: faUpload,
action: () => { this.selectLocalFile(); }
}, {
text: this.$t('fromUrl'),
text: this.$ts.fromUrl,
icon: faLink,
action: () => { this.urlUpload(); }
}, null, {
text: this.folder ? this.folder.name : this.$t('drive'),
text: this.folder ? this.folder.name : this.$ts.drive,
type: 'label'
}, this.folder ? {
text: this.$t('renameFolder'),
text: this.$ts.renameFolder,
icon: faICursor,
action: () => { this.renameFolder(this.folder); }
} : undefined, this.folder ? {
text: this.$t('deleteFolder'),
text: this.$ts.deleteFolder,
icon: faTrashAlt,
action: () => { this.deleteFolder(this.folder); }
} : undefined, {
text: this.$t('createFolder'),
text: this.$ts.createFolder,
icon: faFolderPlus,
action: () => { this.createFolder(); }
}];

View File

@ -1,7 +1,7 @@
<template>
<MkModal ref="modal" :src="src" @click="$refs.modal.close()" @closed="$emit('closed')">
<div class="omfetrab _popup" :class="['w' + width, 'h' + height, { big }]">
<input ref="search" class="search" :class="{ filled: q != null && q != '' }" v-model.trim="q" :placeholder="$t('search')" @paste.stop="paste" @keyup.enter="done()">
<input ref="search" class="search" :class="{ filled: q != null && q != '' }" v-model.trim="q" :placeholder="$ts.search" @paste.stop="paste" @keyup.enter="done()">
<div class="emojis">
<section class="result">
<div v-if="searchResultCustom.length > 0">
@ -43,7 +43,7 @@
</section>
<section>
<header class="_acrylic"><Fa :icon="faClock" fixed-width/> {{ $t('recentUsed') }}</header>
<header class="_acrylic"><Fa :icon="faClock" fixed-width/> {{ $ts.recentUsed }}</header>
<div>
<button v-for="emoji in $store.state.recentlyUsedEmojis"
class="_button"
@ -59,7 +59,7 @@
</div>
<section v-for="category in customEmojiCategories" :key="'custom:' + category" class="custom">
<header class="_acrylic" v-appear="() => visibleCategories[category] = true">{{ category || $t('other') }}</header>
<header class="_acrylic" v-appear="() => visibleCategories[category] = true">{{ category || $ts.other }}</header>
<div v-if="visibleCategories[category]">
<button v-for="emoji in customEmojis.filter(e => e.category === category)"
class="_button"

View File

@ -6,23 +6,23 @@
>
<template v-if="!wait">
<template v-if="hasPendingFollowRequestFromYou && user.isLocked">
<span v-if="full">{{ $t('followRequestPending') }}</span><Fa :icon="faHourglassHalf"/>
<span v-if="full">{{ $ts.followRequestPending }}</span><Fa :icon="faHourglassHalf"/>
</template>
<template v-else-if="hasPendingFollowRequestFromYou && !user.isLocked"> <!-- つまりリモートフォローの場合 -->
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse/>
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse/>
</template>
<template v-else-if="isFollowing">
<span v-if="full">{{ $t('unfollow') }}</span><Fa :icon="faMinus"/>
<span v-if="full">{{ $ts.unfollow }}</span><Fa :icon="faMinus"/>
</template>
<template v-else-if="!isFollowing && user.isLocked">
<span v-if="full">{{ $t('followRequest') }}</span><Fa :icon="faPlus"/>
<span v-if="full">{{ $ts.followRequest }}</span><Fa :icon="faPlus"/>
</template>
<template v-else-if="!isFollowing && !user.isLocked">
<span v-if="full">{{ $t('follow') }}</span><Fa :icon="faPlus"/>
<span v-if="full">{{ $ts.follow }}</span><Fa :icon="faPlus"/>
</template>
</template>
<template v-else>
<span v-if="full">{{ $t('processing') }}</span><Fa :icon="faSpinner" pulse fixed-width/>
<span v-if="full">{{ $ts.processing }}</span><Fa :icon="faSpinner" pulse fixed-width/>
</template>
</button>
</template>

View File

@ -15,15 +15,15 @@
<FormBase class="xkpnjxcv">
<template v-for="item in Object.keys(form).filter(item => !form[item].hidden)">
<FormInput v-if="form[item].type === 'number'" v-model:value="values[item]" type="number" :step="form[item].step || 1">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormInput>
<FormInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model:value="values[item]" type="text">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormInput>
<FormTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model:value="values[item]">
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span>
<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormTextarea>
<FormSwitch v-else-if="form[item].type === 'boolean'" v-model:value="values[item]">
@ -31,11 +31,11 @@
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormSwitch>
<FormSelect v-else-if="form[item].type === 'enum'" v-model:value="values[item]">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span></template>
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<option v-for="item in form[item].enum" :value="item.value" :key="item.value">{{ item.label }}</option>
</FormSelect>
<FormRange v-else-if="form[item].type === 'range'" v-model:value="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step">
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $t('optional') }})</span></template>
<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
</FormRange>
<FormButton v-else-if="form[item].type === 'button'" @click="form[item].action($event, values)">

View File

@ -44,7 +44,7 @@
</datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="_formCaption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -6,7 +6,7 @@
<slot name="empty"></slot>
</div>
<FormButton v-show="more" class="button" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary>
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</FormButton>
</FormGroup>

View File

@ -14,7 +14,7 @@
@blur="focused = false"
></textarea>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="_formCaption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -58,31 +58,31 @@ export default defineComponent({
text: this.to,
}, {
icon: faWindowMaximize,
text: this.$t('openInWindow'),
text: this.$ts.openInWindow,
action: () => {
os.pageWindow(this.to);
}
}, this.sideViewHook ? {
icon: faColumns,
text: this.$t('openInSideView'),
text: this.$ts.openInSideView,
action: () => {
this.sideViewHook(this.to);
}
} : undefined, {
icon: faExpandAlt,
text: this.$t('showInPage'),
text: this.$ts.showInPage,
action: () => {
this.$router.push(this.to);
}
}, null, {
icon: faExternalLinkAlt,
text: this.$t('openInNewTab'),
text: this.$ts.openInNewTab,
action: () => {
window.open(this.to, '_blank');
}
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: () => {
copyToClipboard(`${url}${this.to}`);
}

View File

@ -2,8 +2,8 @@
<transition :name="$store.state.animation ? 'zoom' : ''" appear>
<div class="mjndxjcg">
<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
<p><Fa :icon="faExclamationTriangle"/> {{ $t('somethingHappened') }}</p>
<MkButton @click="() => $emit('retry')" class="button">{{ $t('retry') }}</MkButton>
<p><Fa :icon="faExclamationTriangle"/> {{ $ts.somethingHappened }}</p>
<MkButton @click="() => $emit('retry')" class="button">{{ $ts.retry }}</MkButton>
</div>
</transition>
</template>

View File

@ -1,15 +1,37 @@
import { h, Fragment, defineComponent } from 'vue';
import type { SetupContext, VNodeChild, RenderFunction } from 'vue';
import { h, defineComponent } from 'vue';
export default defineComponent({
props: {
src: {
type: String,
required: true
required: true,
},
tag: {
type: String,
required: false,
default: 'span',
},
},
render() {
// TODO
return h('span', this.src);
let str = this.src;
const parsed = [] as (string | { arg: string; })[];
while (true) {
const nextBracketOpen = str.indexOf('{');
const nextBracketClose = str.indexOf('}');
if (nextBracketOpen === -1) {
parsed.push(str);
break;
} else {
if (nextBracketOpen > 0) parsed.push(str.substr(0, nextBracketOpen));
parsed.push({
arg: str.substring(nextBracketOpen + 1, nextBracketClose)
});
}
str = str.substr(nextBracketClose + 1);
}
return h(this.tag, parsed.map(x => typeof x === 'string' ? x : this.$slots[x.arg]()));
}
});

View File

@ -44,9 +44,9 @@ export default defineComponent({
ago >= 3600 ? this.$t('_ago.hoursAgo', { n: (~~(ago / 3600)).toString() }) :
ago >= 60 ? this.$t('_ago.minutesAgo', { n: (~~(ago / 60)).toString() }) :
ago >= 10 ? this.$t('_ago.secondsAgo', { n: (~~(ago % 60)).toString() }) :
ago >= -1 ? this.$t('_ago.justNow') :
ago < -1 ? this.$t('_ago.future') :
this.$t('_ago.unknown'));
ago >= -1 ? this.$ts._ago.justNow :
ago < -1 ? this.$ts._ago.future :
this.$ts._ago.unknown);
}
},
created() {

View File

@ -1,7 +1,7 @@
<template>
<div class="mk-google">
<input type="search" v-model="query" :placeholder="q">
<button @click="search"><Fa :icon="faSearch"/> {{ $t('search') }}</button>
<button @click="search"><Fa :icon="faSearch"/> {{ $ts.search }}</button>
</div>
</template>

View File

@ -3,80 +3,80 @@
<div class="stats" v-if="info">
<div class="_panel">
<div>
<b><Fa :icon="faUser"/>{{ $t('users') }}</b>
<small>{{ $t('local') }}</small>
<b><Fa :icon="faUser"/>{{ $ts.users }}</b>
<small>{{ $ts.local }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number(info.originalUsersCount) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersLocalDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(usersLocalDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersLocalWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(usersLocalWoW) }}</dd>
</dl>
</div>
</div>
<div class="_panel">
<div>
<b><Fa :icon="faUser"/>{{ $t('users') }}</b>
<small>{{ $t('remote') }}</small>
<b><Fa :icon="faUser"/>{{ $ts.users }}</b>
<small>{{ $ts.remote }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number((info.usersCount - info.originalUsersCount)) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersRemoteDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(usersRemoteDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: usersRemoteWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(usersRemoteWoW) }}</dd>
</dl>
</div>
</div>
<div class="_panel">
<div>
<b><Fa :icon="faPencilAlt"/>{{ $t('notes') }}</b>
<small>{{ $t('local') }}</small>
<b><Fa :icon="faPencilAlt"/>{{ $ts.notes }}</b>
<small>{{ $ts.local }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number(info.originalNotesCount) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesLocalDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(notesLocalDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesLocalWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(notesLocalWoW) }}</dd>
</dl>
</div>
</div>
<div class="_panel">
<div>
<b><Fa :icon="faPencilAlt"/>{{ $t('notes') }}</b>
<small>{{ $t('remote') }}</small>
<b><Fa :icon="faPencilAlt"/>{{ $ts.notes }}</b>
<small>{{ $ts.remote }}</small>
</div>
<div>
<dl class="total">
<dt>{{ $t('total') }}</dt>
<dt>{{ $ts.total }}</dt>
<dd>{{ number((info.notesCount - info.originalNotesCount)) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesRemoteDoD > 0 }">
<dt>{{ $t('dayOverDayChanges') }}</dt>
<dt>{{ $ts.dayOverDayChanges }}</dt>
<dd>{{ number(notesRemoteDoD) }}</dd>
</dl>
<dl class="diff" :class="{ inc: notesRemoteWoW > 0 }">
<dt>{{ $t('weekOverWeekChanges') }}</dt>
<dt>{{ $ts.weekOverWeekChanges }}</dt>
<dd>{{ number(notesRemoteWoW) }}</dd>
</dl>
</div>
@ -84,35 +84,35 @@
</div>
<section class="_card">
<div class="_title" style="position: relative;"><Fa :icon="faChartBar"/> {{ $t('statistics') }}<button @click="fetchChart" class="_button" style="position: absolute; right: 0; bottom: 0; top: 0; padding: inherit;"><Fa :icon="faSync"/></button></div>
<div class="_title" style="position: relative;"><Fa :icon="faChartBar"/> {{ $ts.statistics }}<button @click="fetchChart" class="_button" style="position: absolute; right: 0; bottom: 0; top: 0; padding: inherit;"><Fa :icon="faSync"/></button></div>
<div class="_content" style="margin-top: -8px;">
<div class="selects" style="display: flex;">
<MkSelect v-model:value="chartSrc" style="margin: 0; flex: 1;">
<optgroup :label="$t('federation')">
<option value="federation-instances">{{ $t('_charts.federationInstancesIncDec') }}</option>
<option value="federation-instances-total">{{ $t('_charts.federationInstancesTotal') }}</option>
<optgroup :label="$ts.federation">
<option value="federation-instances">{{ $ts._charts.federationInstancesIncDec }}</option>
<option value="federation-instances-total">{{ $ts._charts.federationInstancesTotal }}</option>
</optgroup>
<optgroup :label="$t('users')">
<option value="users">{{ $t('_charts.usersIncDec') }}</option>
<option value="users-total">{{ $t('_charts.usersTotal') }}</option>
<option value="active-users">{{ $t('_charts.activeUsers') }}</option>
<optgroup :label="$ts.users">
<option value="users">{{ $ts._charts.usersIncDec }}</option>
<option value="users-total">{{ $ts._charts.usersTotal }}</option>
<option value="active-users">{{ $ts._charts.activeUsers }}</option>
</optgroup>
<optgroup :label="$t('notes')">
<option value="notes">{{ $t('_charts.notesIncDec') }}</option>
<option value="local-notes">{{ $t('_charts.localNotesIncDec') }}</option>
<option value="remote-notes">{{ $t('_charts.remoteNotesIncDec') }}</option>
<option value="notes-total">{{ $t('_charts.notesTotal') }}</option>
<optgroup :label="$ts.notes">
<option value="notes">{{ $ts._charts.notesIncDec }}</option>
<option value="local-notes">{{ $ts._charts.localNotesIncDec }}</option>
<option value="remote-notes">{{ $ts._charts.remoteNotesIncDec }}</option>
<option value="notes-total">{{ $ts._charts.notesTotal }}</option>
</optgroup>
<optgroup :label="$t('drive')">
<option value="drive-files">{{ $t('_charts.filesIncDec') }}</option>
<option value="drive-files-total">{{ $t('_charts.filesTotal') }}</option>
<option value="drive">{{ $t('_charts.storageUsageIncDec') }}</option>
<option value="drive-total">{{ $t('_charts.storageUsageTotal') }}</option>
<optgroup :label="$ts.drive">
<option value="drive-files">{{ $ts._charts.filesIncDec }}</option>
<option value="drive-files-total">{{ $ts._charts.filesTotal }}</option>
<option value="drive">{{ $ts._charts.storageUsageIncDec }}</option>
<option value="drive-total">{{ $ts._charts.storageUsageTotal }}</option>
</optgroup>
</MkSelect>
<MkSelect v-model:value="chartSpan" style="margin: 0;">
<option value="hour">{{ $t('perHour') }}</option>
<option value="day">{{ $t('perDay') }}</option>
<option value="hour">{{ $ts.perHour }}</option>
<option value="day">{{ $ts.perDay }}</option>
</MkSelect>
</div>
<canvas ref="chart"></canvas>

View File

@ -18,7 +18,7 @@
<div class="sub">
<MkA to="/docs" @click.passive="close()">
<Fa :icon="faQuestionCircle" class="icon"/>
<div class="text">{{ $t('help') }}</div>
<div class="text">{{ $ts.help }}</div>
</MkA>
<MkA to="/about" @click.passive="close()">
<Fa :icon="faInfoCircle" class="icon"/>
@ -26,7 +26,7 @@
</MkA>
<MkA to="/about-misskey" @click.passive="close()">
<Fa :icon="faInfoCircle" class="icon"/>
<div class="text">{{ $t('aboutMisskey') }}</div>
<div class="text">{{ $ts.aboutMisskey }}</div>
</MkA>
</div>
</div>

View File

@ -2,8 +2,8 @@
<div class="mk-media-banner">
<div class="sensitive" v-if="media.isSensitive && hide" @click="hide = false">
<span class="icon"><Fa :icon="faExclamationTriangle"/></span>
<b>{{ $t('sensitive') }}</b>
<span>{{ $t('clickToShow') }}</span>
<b>{{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span>
</div>
<div class="audio" v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'">
<audio class="audio"

View File

@ -3,8 +3,8 @@
<ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.name"/>
<div class="text">
<div>
<b><Fa :icon="faExclamationTriangle"/> {{ $t('sensitive') }}</b>
<span>{{ $t('clickToShow') }}</span>
<b><Fa :icon="faExclamationTriangle"/> {{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span>
</div>
</div>
</div>

View File

@ -1,8 +1,8 @@
<template>
<div class="icozogqfvdetwohsdglrbswgrejoxbdj" v-if="hide" @click="hide = false">
<div>
<b><Fa :icon="faExclamationTriangle"/> {{ $t('sensitive') }}</b>
<span>{{ $t('clickToShow') }}</span>
<b><Fa :icon="faExclamationTriangle"/> {{ $ts.sensitive }}</b>
<span>{{ $ts.clickToShow }}</span>
</div>
</div>
<div class="kkjnbbplepmiyuadieoenjgutgcmtsvu" v-else>

View File

@ -1,6 +1,6 @@
<template>
<MkA class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" v-if="url.startsWith('/')">
<span class="me" v-if="isMe">{{ $t('you') }}</span>
<span class="me" v-if="isMe">{{ $ts.you }}</span>
<span class="main">
<span class="username">@{{ username }}</span>
<span class="host" v-if="(host != localHost) || $store.state.showFullAcct">@{{ toUnicode(host) }}</span>

View File

@ -10,13 +10,13 @@
>
<XSub v-for="note in conversation" class="reply-to-more" :key="note.id" :note="note"/>
<XSub :note="appearNote.reply" class="reply-to" v-if="appearNote.reply"/>
<div class="info" v-if="pinned"><Fa :icon="faThumbtack"/> {{ $t('pinnedNote') }}</div>
<div class="info" v-if="appearNote._prId_"><Fa :icon="faBullhorn"/> {{ $t('promotion') }}<button class="_textButton hide" @click="readPromo()">{{ $t('hideThisNote') }} <Fa :icon="faTimes"/></button></div>
<div class="info" v-if="appearNote._featuredId_"><Fa :icon="faBolt"/> {{ $t('featured') }}</div>
<div class="info" v-if="pinned"><Fa :icon="faThumbtack"/> {{ $ts.pinnedNote }}</div>
<div class="info" v-if="appearNote._prId_"><Fa :icon="faBullhorn"/> {{ $ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ $ts.hideThisNote }} <Fa :icon="faTimes"/></button></div>
<div class="info" v-if="appearNote._featuredId_"><Fa :icon="faBolt"/> {{ $ts.featured }}</div>
<div class="renote" v-if="isRenote">
<MkAvatar class="avatar" :user="note.user"/>
<Fa :icon="faRetweet"/>
<I18n src="renotedBy" tag="span">
<I18n :src="$ts.renotedBy" tag="span">
<template #user>
<MkA class="name" :to="userPage(note.user)" v-user-preview="note.userId">
<MkUserName :user="note.user"/>
@ -48,7 +48,7 @@
</p>
<div class="content" v-show="appearNote.cw == null || showContent">
<div class="text">
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $ts.private }})</span>
<MkA class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><Fa :icon="faReply"/></MkA>
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
<a class="rp" v-if="appearNote.renote != null">RN:</a>
@ -90,7 +90,7 @@
<XSub v-for="note in replies" :key="note.id" :note="note" class="reply" :detail="true"/>
</div>
<div v-else class="_panel muted" @click="muted = false">
<I18n src="userSaysSomething" tag="small">
<I18n :src="$ts.userSaysSomething" tag="small">
<template #name>
<MkA class="name" :to="userPage(appearNote.user)" v-user-preview="appearNote.userId">
<MkUserName :user="appearNote.user"/>
@ -469,7 +469,7 @@ export default defineComponent({
pleaseLogin();
this.blur();
os.modalMenu([{
text: this.$t('renote'),
text: this.$ts.renote,
icon: faRetweet,
action: () => {
os.api('notes/create', {
@ -477,7 +477,7 @@ export default defineComponent({
});
}
}, {
text: this.$t('quote'),
text: this.$ts.quote,
icon: faQuoteRight,
action: () => {
os.post({
@ -495,18 +495,18 @@ export default defineComponent({
}, undefined, (res: any) => {
os.dialog({
type: 'success',
text: this.$t('renoted'),
text: this.$ts.renoted,
});
}, (e: Error) => {
if (e.id === 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4') {
os.dialog({
type: 'error',
text: this.$t('cantRenote'),
text: this.$ts.cantRenote,
});
} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
os.dialog({
type: 'error',
text: this.$t('cantReRenote'),
text: this.$ts.cantReRenote,
});
}
});
@ -553,18 +553,18 @@ export default defineComponent({
}, undefined, (res: any) => {
os.dialog({
type: 'success',
text: this.$t('favorited'),
text: this.$ts.favorited,
});
}, (e: Error) => {
if (e.id === 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6') {
os.dialog({
type: 'error',
text: this.$t('alreadyFavorited'),
text: this.$ts.alreadyFavorited,
});
} else if (e.id === '6dd26674-e060-4816-909a-45ba3f4da458') {
os.dialog({
type: 'error',
text: this.$t('cantFavorite'),
text: this.$ts.cantFavorite,
});
}
});
@ -573,7 +573,7 @@ export default defineComponent({
del() {
os.dialog({
type: 'warning',
text: this.$t('noteDeleteConfirm'),
text: this.$ts.noteDeleteConfirm,
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
@ -587,7 +587,7 @@ export default defineComponent({
delEdit() {
os.dialog({
type: 'warning',
text: this.$t('deleteAndEditConfirm'),
text: this.$ts.deleteAndEditConfirm,
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) return;
@ -621,15 +621,15 @@ export default defineComponent({
menu = [{
icon: faCopy,
text: this.$t('copyContent'),
text: this.$ts.copyContent,
action: this.copyContent
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: this.copyLink
}, (this.appearNote.url || this.appearNote.uri) ? {
icon: faExternalLinkSquareAlt,
text: this.$t('showOnRemote'),
text: this.$ts.showOnRemote,
action: () => {
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
}
@ -637,41 +637,41 @@ export default defineComponent({
null,
statePromise.then(state => state.isFavorited ? {
icon: faStar,
text: this.$t('unfavorite'),
text: this.$ts.unfavorite,
action: () => this.toggleFavorite(false)
} : {
icon: faStar,
text: this.$t('favorite'),
text: this.$ts.favorite,
action: () => this.toggleFavorite(true)
}),
{
icon: faPaperclip,
text: this.$t('clip'),
text: this.$ts.clip,
action: () => this.clip()
},
(this.appearNote.userId != this.$i.id) ? statePromise.then(state => state.isWatching ? {
icon: faEyeSlash,
text: this.$t('unwatch'),
text: this.$ts.unwatch,
action: () => this.toggleWatch(false)
} : {
icon: faEye,
text: this.$t('watch'),
text: this.$ts.watch,
action: () => this.toggleWatch(true)
}) : undefined,
this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
icon: faThumbtack,
text: this.$t('unpin'),
text: this.$ts.unpin,
action: () => this.togglePin(false)
} : {
icon: faThumbtack,
text: this.$t('pin'),
text: this.$ts.pin,
action: () => this.togglePin(true)
} : undefined,
...(this.$i.isModerator || this.$i.isAdmin ? [
null,
{
icon: faBullhorn,
text: this.$t('promote'),
text: this.$ts.promote,
action: this.promote
}]
: []
@ -680,7 +680,7 @@ export default defineComponent({
null,
{
icon: faExclamationCircle,
text: this.$t('reportAbuse'),
text: this.$ts.reportAbuse,
action: () => {
const u = `${url}/notes/${this.appearNote.id}`;
os.popup(import('@/components/abuse-report-window.vue'), {
@ -695,12 +695,12 @@ export default defineComponent({
null,
this.appearNote.userId == this.$i.id ? {
icon: faEdit,
text: this.$t('deleteAndEdit'),
text: this.$ts.deleteAndEdit,
action: this.delEdit
} : undefined,
{
icon: faTrashAlt,
text: this.$t('delete'),
text: this.$ts.delete,
danger: true,
action: this.del
}]
@ -710,15 +710,15 @@ export default defineComponent({
} else {
menu = [{
icon: faCopy,
text: this.$t('copyContent'),
text: this.$ts.copyContent,
action: this.copyContent
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: this.copyLink
}, (this.appearNote.url || this.appearNote.uri) ? {
icon: faExternalLinkSquareAlt,
text: this.$t('showOnRemote'),
text: this.$ts.showOnRemote,
action: () => {
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
}
@ -760,7 +760,7 @@ export default defineComponent({
showRenoteMenu(viaKeyboard = false) {
if (!this.isMyRenote) return;
os.modalMenu([{
text: this.$t('unrenote'),
text: this.$ts.unrenote,
icon: faTrashAlt,
danger: true,
action: () => {
@ -795,7 +795,7 @@ export default defineComponent({
if (e.id === '72dab508-c64d-498f-8740-a8eec1ba385a') {
os.dialog({
type: 'error',
text: this.$t('pinLimitExceeded')
text: this.$ts.pinLimitExceeded
});
}
});
@ -805,22 +805,22 @@ export default defineComponent({
const clips = await os.api('clips/list');
os.modalMenu([{
icon: faPlus,
text: this.$t('createNew'),
text: this.$ts.createNew,
action: async () => {
const { canceled, result } = await os.form(this.$t('createNewClip'), {
const { canceled, result } = await os.form(this.$ts.createNewClip, {
name: {
type: 'string',
label: this.$t('name')
label: this.$ts.name
},
description: {
type: 'string',
required: false,
multiline: true,
label: this.$t('description')
label: this.$ts.description
},
isPublic: {
type: 'boolean',
label: this.$t('public'),
label: this.$ts.public,
default: false
}
});
@ -841,7 +841,7 @@ export default defineComponent({
async promote() {
const { canceled, result: days } = await os.dialog({
title: this.$t('numberOfDays'),
title: this.$ts.numberOfDays,
input: { type: 'number' }
});

View File

@ -2,14 +2,14 @@
<div class="_list_">
<div class="_fullinfo" v-if="empty">
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
<div>{{ $t('noNotes') }}</div>
<div>{{ $ts.noNotes }}</div>
</div>
<MkError v-if="error" @retry="init()"/>
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
<button class="_loadMore" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</button>
</div>
@ -20,7 +20,7 @@
<div v-show="more && !reversed" style="margin-top: var(--margin);">
<button class="_loadMore" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</button>
</div>

View File

@ -8,17 +8,17 @@
@close="$refs.dialog.close()"
@closed="$emit('closed')"
>
<template #header>{{ $t('notificationSetting') }}</template>
<template #header>{{ $ts.notificationSetting }}</template>
<div v-if="showGlobalToggle" class="_section">
<MkSwitch v-model:value="useGlobalSetting">
{{ $t('useGlobalSetting') }}
<template #desc>{{ $t('useGlobalSettingDesc') }}</template>
{{ $ts.useGlobalSetting }}
<template #desc>{{ $ts.useGlobalSettingDesc }}</template>
</MkSwitch>
</div>
<div v-if="!useGlobalSetting" class="_section">
<MkInfo>{{ $t('notificationSettingDesc') }}</MkInfo>
<MkButton inline @click="disableAll">{{ $t('disableAll') }}</MkButton>
<MkButton inline @click="enableAll">{{ $t('enableAll') }}</MkButton>
<MkInfo>{{ $ts.notificationSettingDesc }}</MkInfo>
<MkButton inline @click="disableAll">{{ $ts.disableAll }}</MkButton>
<MkButton inline @click="enableAll">{{ $ts.enableAll }}</MkButton>
<MkSwitch v-for="type in notificationTypes" :key="type" v-model:value="typesMap[type]">{{ $t(`_notification._types.${type}`) }}</MkSwitch>
</div>
</XModalWindow>

View File

@ -46,10 +46,10 @@
<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
<Fa :icon="faQuoteRight"/>
</MkA>
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ $t('youGotNewFollower') }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ $t('followRequestAccepted') }}</span>
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ $t('receiveFollowRequest') }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ $t('accept') }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ $t('reject') }}</button></div></span>
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ $t('groupInvited') }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ $t('accept') }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ $t('reject') }}</button></div></span>
<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ $ts.youGotNewFollower }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ $ts.followRequestAccepted }}</span>
<span v-if="notification.type === 'receiveFollowRequest'" class="text" style="opacity: 0.6;">{{ $ts.receiveFollowRequest }}<div v-if="full && !followRequestDone"><button class="_textButton" @click="acceptFollowRequest()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectFollowRequest()">{{ $ts.reject }}</button></div></span>
<span v-if="notification.type === 'groupInvited'" class="text" style="opacity: 0.6;">{{ $ts.groupInvited }}: <b>{{ notification.invitation.group.name }}</b><div v-if="full && !groupInviteDone"><button class="_textButton" @click="acceptGroupInvitation()">{{ $ts.accept }}</button> | <button class="_textButton" @click="rejectGroupInvitation()">{{ $ts.reject }}</button></div></span>
<span v-if="notification.type === 'app'" class="text">
<Mfm :text="notification.body" :nowrap="!full"/>
</span>

View File

@ -6,11 +6,11 @@
</XList>
<button class="_loadMore" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" v-show="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</button>
<p class="empty" v-if="empty">{{ $t('noNotifications') }}</p>
<p class="empty" v-if="empty">{{ $ts.noNotifications }}</p>
<MkError v-if="error" @retry="init()"/>
</div>

View File

@ -90,29 +90,29 @@ export default defineComponent({
text: this.path,
}, {
icon: faExpandAlt,
text: this.$t('showInPage'),
text: this.$ts.showInPage,
action: this.expand
}, this.sideViewHook ? {
icon: faColumns,
text: this.$t('openInSideView'),
text: this.$ts.openInSideView,
action: () => {
this.sideViewHook(this.path);
this.$refs.window.close();
}
} : undefined, {
icon: faExternalLinkAlt,
text: this.$t('popout'),
text: this.$ts.popout,
action: this.popout
}, null, {
icon: faExternalLinkAlt,
text: this.$t('openInNewTab'),
text: this.$ts.openInNewTab,
action: () => {
window.open(this.url, '_blank');
this.$refs.window.close();
}
}, {
icon: faLink,
text: this.$t('copyLink'),
text: this.$ts.copyLink,
action: () => {
copyToClipboard(this.url);
}

View File

@ -1,7 +1,7 @@
<template>
<div class="zmdxowus">
<p class="caution" v-if="choices.length < 2">
<Fa :icon="faExclamationTriangle"/>{{ $t('_poll.noOnlyOneChoice') }}
<Fa :icon="faExclamationTriangle"/>{{ $ts._poll.noOnlyOneChoice }}
</p>
<ul ref="choices">
<li v-for="(choice, i) in choices" :key="i">
@ -13,34 +13,34 @@
</button>
</li>
</ul>
<MkButton class="add" v-if="choices.length < 10" @click="add">{{ $t('add') }}</MkButton>
<MkButton class="add" v-else disabled>{{ $t('_poll.noMore') }}</MkButton>
<MkButton class="add" v-if="choices.length < 10" @click="add">{{ $ts.add }}</MkButton>
<MkButton class="add" v-else disabled>{{ $ts._poll.noMore }}</MkButton>
<section>
<MkSwitch v-model:value="multiple">{{ $t('_poll.canMultipleVote') }}</MkSwitch>
<MkSwitch v-model:value="multiple">{{ $ts._poll.canMultipleVote }}</MkSwitch>
<div>
<MkSelect v-model:value="expiration">
<template #label>{{ $t('_poll.expiration') }}</template>
<option value="infinite">{{ $t('_poll.infinite') }}</option>
<option value="at">{{ $t('_poll.at') }}</option>
<option value="after">{{ $t('_poll.after') }}</option>
<template #label>{{ $ts._poll.expiration }}</template>
<option value="infinite">{{ $ts._poll.infinite }}</option>
<option value="at">{{ $ts._poll.at }}</option>
<option value="after">{{ $ts._poll.after }}</option>
</MkSelect>
<section v-if="expiration === 'at'">
<MkInput v-model:value="atDate" type="date" class="input">
<span>{{ $t('_poll.deadlineDate') }}</span>
<span>{{ $ts._poll.deadlineDate }}</span>
</MkInput>
<MkInput v-model:value="atTime" type="time" class="input">
<span>{{ $t('_poll.deadlineTime') }}</span>
<span>{{ $ts._poll.deadlineTime }}</span>
</MkInput>
</section>
<section v-if="expiration === 'after'">
<MkInput v-model:value="after" type="number" class="input">
<span>{{ $t('_poll.duration') }}</span>
<span>{{ $ts._poll.duration }}</span>
</MkInput>
<MkSelect v-model:value="unit">
<option value="second">{{ $t('_time.second') }}</option>
<option value="minute">{{ $t('_time.minute') }}</option>
<option value="hour">{{ $t('_time.hour') }}</option>
<option value="day">{{ $t('_time.day') }}</option>
<option value="second">{{ $ts._time.second }}</option>
<option value="minute">{{ $ts._time.minute }}</option>
<option value="hour">{{ $ts._time.hour }}</option>
<option value="day">{{ $ts._time.day }}</option>
</MkSelect>
</section>
</div>

View File

@ -13,9 +13,9 @@
<p>
<span>{{ $t('_poll.totalVotes', { n: total }) }}</span>
<span> · </span>
<a v-if="!closed && !isVoted" @click="toggleShowResult">{{ showResult ? $t('_poll.vote') : $t('_poll.showResult') }}</a>
<span v-if="isVoted">{{ $t('_poll.voted') }}</span>
<span v-else-if="closed">{{ $t('_poll.closed') }}</span>
<a v-if="!closed && !isVoted" @click="toggleShowResult">{{ showResult ? $ts._poll.vote : $ts._poll.showResult }}</a>
<span v-if="isVoted">{{ $ts._poll.voted }}</span>
<span v-else-if="closed">{{ $ts._poll.closed }}</span>
<span v-if="remaining > 0"> · {{ timer }}</span>
</p>
</div>

View File

@ -77,7 +77,7 @@ export default defineComponent({
},
async rename(file) {
const { canceled, result } = await os.dialog({
title: this.$t('enterFileName'),
title: this.$ts.enterFileName,
input: {
default: file.name
},
@ -95,15 +95,15 @@ export default defineComponent({
showFileMenu(file, ev: MouseEvent) {
if (this.menu) return;
this.menu = os.modalMenu([{
text: this.$t('renameFile'),
text: this.$ts.renameFile,
icon: faICursor,
action: () => { this.rename(file) }
}, {
text: file.isSensitive ? this.$t('unmarkAsSensitive') : this.$t('markAsSensitive'),
text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive,
icon: file.isSensitive ? faEyeSlash : faEye,
action: () => { this.toggleSensitive(file) }
}, {
text: this.$t('attachCancel'),
text: this.$ts.attachCancel,
icon: faTimesCircle,
action: () => { this.detachMedia(file.id) }
}], ev.currentTarget || ev.target).then(() => this.menu = null);

View File

@ -11,7 +11,7 @@
<div>
<span class="text-count" :class="{ over: trimmedLength(text) > max }">{{ max - trimmedLength(text) }}</span>
<span class="local-only" v-if="localOnly"><Fa :icon="faBiohazard"/></span>
<button class="_button visibility" @click="setVisibility" ref="visibilityButton" v-tooltip="$t('visibility')" :disabled="channel != null">
<button class="_button visibility" @click="setVisibility" ref="visibilityButton" v-tooltip="$ts.visibility" :disabled="channel != null">
<span v-if="visibility === 'public'"><Fa :icon="faGlobe"/></span>
<span v-if="visibility === 'home'"><Fa :icon="faHome"/></span>
<span v-if="visibility === 'followers'"><Fa :icon="faUnlock"/></span>
@ -23,9 +23,9 @@
<div class="form" :class="{ fixed }">
<XNotePreview class="preview" v-if="reply" :note="reply"/>
<XNotePreview class="preview" v-if="renote" :note="renote"/>
<div class="with-quote" v-if="quoteId"><Fa icon="quote-left"/> {{ $t('quoteAttached') }}<button @click="quoteId = null"><Fa icon="times"/></button></div>
<div class="with-quote" v-if="quoteId"><Fa icon="quote-left"/> {{ $ts.quoteAttached }}<button @click="quoteId = null"><Fa icon="times"/></button></div>
<div v-if="visibility === 'specified'" class="to-specified">
<span style="margin-right: 8px;">{{ $t('recipient') }}</span>
<span style="margin-right: 8px;">{{ $ts.recipient }}</span>
<div class="visibleUsers">
<span v-for="u in visibleUsers" :key="u.id">
<MkAcct :user="u"/>
@ -34,17 +34,17 @@
<button @click="addVisibleUser" class="_buttonPrimary"><Fa :icon="faPlus" fixed-width/></button>
</div>
</div>
<input v-show="useCw" ref="cw" class="cw" v-model="cw" :placeholder="$t('annotation')" @keydown="onKeydown">
<input v-show="useCw" ref="cw" class="cw" v-model="cw" :placeholder="$ts.annotation" @keydown="onKeydown">
<textarea v-model="text" class="text" :class="{ withCw: useCw }" ref="text" :disabled="posting" :placeholder="placeholder" @keydown="onKeydown" @paste="onPaste"></textarea>
<XPostFormAttaches class="attaches" :files="files" @updated="updateFiles" @detach="detachFile" @changeSensitive="updateFileSensitive" @changeName="updateFileName"/>
<XPollEditor v-if="poll" :poll="poll" @destroyed="poll = null" @updated="onPollUpdate"/>
<footer>
<button class="_button" @click="chooseFileFrom" v-tooltip="$t('attachFile')"><Fa :icon="faPhotoVideo"/></button>
<button class="_button" @click="togglePoll" :class="{ active: poll }" v-tooltip="$t('poll')"><Fa :icon="faPollH"/></button>
<button class="_button" @click="useCw = !useCw" :class="{ active: useCw }" v-tooltip="$t('useCw')"><Fa :icon="faEyeSlash"/></button>
<button class="_button" @click="insertMention" v-tooltip="$t('mention')"><Fa :icon="faAt"/></button>
<button class="_button" @click="insertEmoji" v-tooltip="$t('emoji')"><Fa :icon="faLaughSquint"/></button>
<button class="_button" @click="showActions" v-tooltip="$t('plugin')" v-if="postFormActions.length > 0"><Fa :icon="faPlug"/></button>
<button class="_button" @click="chooseFileFrom" v-tooltip="$ts.attachFile"><Fa :icon="faPhotoVideo"/></button>
<button class="_button" @click="togglePoll" :class="{ active: poll }" v-tooltip="$ts.poll"><Fa :icon="faPollH"/></button>
<button class="_button" @click="useCw = !useCw" :class="{ active: useCw }" v-tooltip="$ts.useCw"><Fa :icon="faEyeSlash"/></button>
<button class="_button" @click="insertMention" v-tooltip="$ts.mention"><Fa :icon="faAt"/></button>
<button class="_button" @click="insertEmoji" v-tooltip="$ts.emoji"><Fa :icon="faLaughSquint"/></button>
<button class="_button" @click="showActions" v-tooltip="$ts.plugin" v-if="postFormActions.length > 0"><Fa :icon="faPlug"/></button>
</footer>
</div>
</div>
@ -164,19 +164,19 @@ export default defineComponent({
placeholder(): string {
if (this.renote) {
return this.$t('_postForm.quotePlaceholder');
return this.$ts._postForm.quotePlaceholder;
} else if (this.reply) {
return this.$t('_postForm.replyPlaceholder');
return this.$ts._postForm.replyPlaceholder;
} else if (this.channel) {
return this.$t('_postForm.channelPlaceholder');
return this.$ts._postForm.channelPlaceholder;
} else {
const xs = [
this.$t('_postForm._placeholders.a'),
this.$t('_postForm._placeholders.b'),
this.$t('_postForm._placeholders.c'),
this.$t('_postForm._placeholders.d'),
this.$t('_postForm._placeholders.e'),
this.$t('_postForm._placeholders.f')
this.$ts._postForm._placeholders.a,
this.$ts._postForm._placeholders.b,
this.$ts._postForm._placeholders.c,
this.$ts._postForm._placeholders.d,
this.$ts._postForm._placeholders.e,
this.$ts._postForm._placeholders.f
];
return xs[Math.floor(Math.random() * xs.length)];
}
@ -184,10 +184,10 @@ export default defineComponent({
submitText(): string {
return this.renote
? this.$t('quote')
? this.$ts.quote
: this.reply
? this.$t('reply')
: this.$t('note');
? this.$ts.reply
: this.$ts.note;
},
canPost(): boolean {
@ -352,7 +352,7 @@ export default defineComponent({
},
chooseFileFrom(ev) {
selectFile(ev.currentTarget || ev.target, this.$t('attachFile'), true).then(files => {
selectFile(ev.currentTarget || ev.target, this.$ts.attachFile, true).then(files => {
for (const file of files) {
this.files.push(file);
}
@ -452,7 +452,7 @@ export default defineComponent({
os.dialog({
type: 'info',
text: this.$t('quoteQuestion'),
text: this.$ts.quoteQuestion,
showCancelButton: true
}).then(({ canceled }) => {
if (canceled) {

View File

@ -1,5 +1,5 @@
<template>
<div class="jmgmzlwq _panel"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/>{{ $t('remoteUserCaution') }}<a :href="href" rel="nofollow noopener" target="_blank">{{ $t('showOnRemote') }}</a></div>
<div class="jmgmzlwq _panel"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/>{{ $ts.remoteUserCaution }}<a :href="href" rel="nofollow noopener" target="_blank">{{ $ts.showOnRemote }}</a></div>
</template>
<script lang="ts">

View File

@ -15,7 +15,7 @@
<MkAvatar :user="$i" class="avatar"/><MkAcct class="text" :user="$i"/>
</button>
<MkA class="item index" active-class="active" to="/" exact>
<Fa :icon="faHome" fixed-width/><span class="text">{{ $t('timeline') }}</span>
<Fa :icon="faHome" fixed-width/><span class="text">{{ $ts.timeline }}</span>
</MkA>
<template v-for="item in menu">
<div v-if="item === '-'" class="divider"></div>
@ -26,14 +26,14 @@
</template>
<div class="divider"></div>
<button class="item _button" :class="{ active: $route.path === '/instance' || $route.path.startsWith('/instance/') }" v-if="$i.isAdmin || $i.isModerator" @click="oepnInstanceMenu">
<Fa :icon="faServer" fixed-width/><span class="text">{{ $t('instance') }}</span>
<Fa :icon="faServer" fixed-width/><span class="text">{{ $ts.instance }}</span>
</button>
<button class="item _button" @click="more">
<Fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $t('more') }}</span>
<Fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $ts.more }}</span>
<i v-if="otherNavItemIndicated"><Fa :icon="faCircle"/></i>
</button>
<MkA class="item" active-class="active" to="/settings">
<Fa :icon="faCog" fixed-width/><span class="text">{{ $t('settings') }}</span>
<Fa :icon="faCog" fixed-width/><span class="text">{{ $ts.settings }}</span>
</MkA>
</div>
</nav>
@ -121,7 +121,7 @@ export default defineComponent({
if (this.searching) return;
os.dialog({
title: this.$t('search'),
title: this.$ts.search,
input: true
}).then(async ({ canceled, result: query }) => {
if (canceled || query == null || query === '') return;
@ -145,18 +145,18 @@ export default defineComponent({
os.modalMenu([...[{
type: 'link',
text: this.$t('profile'),
text: this.$ts.profile,
to: `/@${ this.$i.username }`,
avatar: this.$i,
}, null, ...accountItems, {
icon: faPlus,
text: this.$t('addAcount'),
text: this.$ts.addAcount,
action: () => {
os.modalMenu([{
text: this.$t('existingAcount'),
text: this.$ts.existingAcount,
action: () => { this.addAcount(); },
}, {
text: this.$t('createAccount'),
text: this.$ts.createAccount,
action: () => { this.createAccount(); },
}], ev.currentTarget || ev.target);
},
@ -168,57 +168,57 @@ export default defineComponent({
oepnInstanceMenu(ev) {
os.modalMenu([{
type: 'link',
text: this.$t('dashboard'),
text: this.$ts.dashboard,
to: '/instance',
icon: faTachometerAlt,
}, null, this.$i.isAdmin ? {
type: 'link',
text: this.$t('settings'),
text: this.$ts.settings,
to: '/instance/settings',
icon: faCog,
} : undefined, {
type: 'link',
text: this.$t('customEmojis'),
text: this.$ts.customEmojis,
to: '/instance/emojis',
icon: faLaugh,
}, {
type: 'link',
text: this.$t('users'),
text: this.$ts.users,
to: '/instance/users',
icon: faUsers,
}, {
type: 'link',
text: this.$t('files'),
text: this.$ts.files,
to: '/instance/files',
icon: faCloud,
}, {
type: 'link',
text: this.$t('jobQueue'),
text: this.$ts.jobQueue,
to: '/instance/queue',
icon: faExchangeAlt,
}, {
type: 'link',
text: this.$t('federation'),
text: this.$ts.federation,
to: '/instance/federation',
icon: faGlobe,
}, {
type: 'link',
text: this.$t('relays'),
text: this.$ts.relays,
to: '/instance/relays',
icon: faProjectDiagram,
}, {
type: 'link',
text: this.$t('announcements'),
text: this.$ts.announcements,
to: '/instance/announcements',
icon: faBroadcastTower,
}, {
type: 'link',
text: this.$t('abuseReports'),
text: this.$ts.abuseReports,
to: '/instance/abuses',
icon: faExclamationCircle,
}, {
type: 'link',
text: this.$t('logs'),
text: this.$ts.logs,
to: '/instance/logs',
icon: faStream,
}], ev.currentTarget || ev.target);

View File

@ -5,7 +5,7 @@
@close="$refs.dialog.close()"
@closed="$emit('closed')"
>
<template #header>{{ $t('login') }}</template>
<template #header>{{ $ts.login }}</template>
<MkSignin :auto-set="autoSet" @login="onLogin"/>
</XModalWindow>

View File

@ -4,37 +4,37 @@
<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
<div class="normal-signin" v-if="!totpLogin">
<MkInput v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:value="onUsernameChange">
<span>{{ $t('username') }}</span>
<span>{{ $ts.username }}</span>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
</MkInput>
<MkInput v-model:value="password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required>
<span>{{ $t('password') }}</span>
<span>{{ $ts.password }}</span>
<template #prefix><Fa :icon="faLock"/></template>
</MkInput>
<MkButton type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $t('loggingIn') : $t('login') }}</MkButton>
<MkButton type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton>
</div>
<div class="2fa-signin" v-if="totpLogin" :class="{ securityKeys: user && user.securityKeys }">
<div v-if="user && user.securityKeys" class="twofa-group tap-group">
<p>{{ $t('tapSecurityKey') }}</p>
<p>{{ $ts.tapSecurityKey }}</p>
<MkButton @click="queryKey" v-if="!queryingKey">
{{ $t('retry') }}
{{ $ts.retry }}
</MkButton>
</div>
<div class="or-hr" v-if="user && user.securityKeys">
<p class="or-msg">{{ $t('or') }}</p>
<p class="or-msg">{{ $ts.or }}</p>
</div>
<div class="twofa-group totp-group">
<p style="margin-bottom:0;">{{ $t('twoStepAuthentication') }}</p>
<p style="margin-bottom:0;">{{ $ts.twoStepAuthentication }}</p>
<MkInput v-model:value="password" type="password" :with-password-toggle="true" v-if="user && user.usePasswordLessLogin" required>
<span>{{ $t('password') }}</span>
<span>{{ $ts.password }}</span>
<template #prefix><Fa :icon="faLock"/></template>
</MkInput>
<MkInput v-model:value="token" type="text" pattern="^[0-9]{6}$" autocomplete="off" spellcheck="false" required>
<span>{{ $t('token') }}</span>
<span>{{ $ts.token }}</span>
<template #prefix><Fa :icon="faGavel"/></template>
</MkInput>
<MkButton type="submit" :disabled="signing" primary style="margin: 0 auto;">{{ signing ? $t('loggingIn') : $t('login') }}</MkButton>
<MkButton type="submit" :disabled="signing" primary style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton>
</div>
</div>
</div>
@ -153,7 +153,7 @@ export default defineComponent({
if (err === null) return;
os.dialog({
type: 'error',
text: this.$t('signinFailed')
text: this.$ts.signinFailed
});
this.signing = false;
});
@ -174,7 +174,7 @@ export default defineComponent({
}).catch(() => {
os.dialog({
type: 'error',
text: this.$t('signinFailed')
text: this.$ts.signinFailed
});
this.challengeData = null;
this.totpLogin = false;
@ -195,7 +195,7 @@ export default defineComponent({
}).catch(() => {
os.dialog({
type: 'error',
text: this.$t('loginFailed')
text: this.$ts.loginFailed
});
this.signing = false;
});

View File

@ -5,7 +5,7 @@
@close="$refs.dialog.close()"
@closed="$emit('closed')"
>
<template #header>{{ $t('signup') }}</template>
<template #header>{{ $ts.signup }}</template>
<div class="_section">
<XSignup :auto-set="autoSet" @signup="onSignup"/>

View File

@ -2,49 +2,49 @@
<form class="mk-signup" @submit.prevent="onSubmit" :autocomplete="Math.random()">
<template v-if="meta">
<MkInput v-if="meta.disableRegistration" v-model:value="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
<span>{{ $t('invitationCode') }}</span>
<span>{{ $ts.invitationCode }}</span>
<template #prefix><Fa :icon="faKey"/></template>
</MkInput>
<MkInput v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:value="onChangeUsername">
<span>{{ $t('username') }}</span>
<span>{{ $ts.username }}</span>
<template #prefix>@</template>
<template #suffix>@{{ host }}</template>
<template #desc>
<span v-if="usernameState == 'wait'" style="color:#999"><Fa :icon="faSpinner" pulse fixed-width/> {{ $t('checking') }}</span>
<span v-if="usernameState == 'ok'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('available') }}</span>
<span v-if="usernameState == 'unavailable'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('unavailable') }}</span>
<span v-if="usernameState == 'error'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('error') }}</span>
<span v-if="usernameState == 'invalid-format'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('usernameInvalidFormat') }}</span>
<span v-if="usernameState == 'min-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('tooShort') }}</span>
<span v-if="usernameState == 'max-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('tooLong') }}</span>
<span v-if="usernameState == 'wait'" style="color:#999"><Fa :icon="faSpinner" pulse fixed-width/> {{ $ts.checking }}</span>
<span v-if="usernameState == 'ok'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.available }}</span>
<span v-if="usernameState == 'unavailable'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.unavailable }}</span>
<span v-if="usernameState == 'error'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.error }}</span>
<span v-if="usernameState == 'invalid-format'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.usernameInvalidFormat }}</span>
<span v-if="usernameState == 'min-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.tooShort }}</span>
<span v-if="usernameState == 'max-range'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.tooLong }}</span>
</template>
</MkInput>
<MkInput v-model:value="password" type="password" :autocomplete="Math.random()" required @update:value="onChangePassword">
<span>{{ $t('password') }}</span>
<span>{{ $ts.password }}</span>
<template #prefix><Fa :icon="faLock"/></template>
<template #desc>
<p v-if="passwordStrength == 'low'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('weakPassword') }}</p>
<p v-if="passwordStrength == 'medium'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('normalPassword') }}</p>
<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('strongPassword') }}</p>
<p v-if="passwordStrength == 'low'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.weakPassword }}</p>
<p v-if="passwordStrength == 'medium'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.normalPassword }}</p>
<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.strongPassword }}</p>
</template>
</MkInput>
<MkInput v-model:value="retypedPassword" type="password" :autocomplete="Math.random()" required @update:value="onChangePasswordRetype">
<span>{{ $t('password') }} ({{ $t('retype') }})</span>
<span>{{ $ts.password }} ({{ $ts.retype }})</span>
<template #prefix><Fa :icon="faLock"/></template>
<template #desc>
<p v-if="passwordRetypeState == 'match'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $t('passwordMatched') }}</p>
<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $t('passwordNotMatched') }}</p>
<p v-if="passwordRetypeState == 'match'" style="color:#3CB7B5"><Fa :icon="faCheck" fixed-width/> {{ $ts.passwordMatched }}</p>
<p v-if="passwordRetypeState == 'not-match'" style="color:#FF1161"><Fa :icon="faExclamationTriangle" fixed-width/> {{ $ts.passwordNotMatched }}</p>
</template>
</MkInput>
<label v-if="meta.tosUrl" class="tou">
<input type="checkbox" v-model="ToSAgreement">
<I18n src="agreeTo">
<a :href="meta.tosUrl" class="_link" target="_blank">{{ $t('tos') }}</a>
<I18n :src="$ts.agreeTo">
<a :href="meta.tosUrl" class="_link" target="_blank">{{ $ts.tos }}</a>
</I18n>
</label>
<captcha v-if="meta.enableHcaptcha" class="captcha" provider="hcaptcha" ref="hcaptcha" v-model:value="hCaptchaResponse" :sitekey="meta.hcaptchaSiteKey"/>
<captcha v-if="meta.enableRecaptcha" class="captcha" provider="grecaptcha" ref="recaptcha" v-model:value="reCaptchaResponse" :sitekey="meta.recaptchaSiteKey"/>
<MkButton type="submit" :disabled="shouldDisableSubmitting" primary>{{ $t('start') }}</MkButton>
<MkButton type="submit" :disabled="shouldDisableSubmitting" primary>{{ $ts.start }}</MkButton>
</template>
</form>
</template>
@ -195,7 +195,7 @@ export default defineComponent({
os.dialog({
type: 'error',
text: this.$t('somethingHappened')
text: this.$ts.somethingHappened
});
});
}

View File

@ -1,8 +1,8 @@
<template>
<div class="wrmlmaau">
<div class="body">
<span v-if="note.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
<span v-if="note.deletedAt" style="opacity: 0.5">({{ $t('deleted') }})</span>
<span v-if="note.isHidden" style="opacity: 0.5">({{ $ts.private }})</span>
<span v-if="note.deletedAt" style="opacity: 0.5">({{ $ts.deleted }})</span>
<MkA class="reply" v-if="note.replyId" :to="`/notes/${note.replyId}`"><Fa :icon="faReply"/></MkA>
<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" :custom-emojis="note.emojis"/>
<MkA class="rp" v-if="note.renoteId" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
@ -12,7 +12,7 @@
<XMediaList :media-list="note.files"/>
</details>
<details v-if="note.poll">
<summary>{{ $t('poll') }}</summary>
<summary>{{ $ts.poll }}</summary>
<XPoll :note="note"/>
</details>
</div>

View File

@ -9,17 +9,17 @@
@closed="$emit('closed')"
@ok="ok()"
>
<template #header>{{ title || $t('generateAccessToken') }}</template>
<template #header>{{ title || $ts.generateAccessToken }}</template>
<div v-if="information" class="_section">
<MkInfo warn>{{ information }}</MkInfo>
</div>
<div class="_section">
<MkInput v-model:value="name">{{ $t('name') }}</MkInput>
<MkInput v-model:value="name">{{ $ts.name }}</MkInput>
</div>
<div class="_section">
<div style="margin-bottom: 16px;"><b>{{ $t('permission') }}</b></div>
<MkButton inline @click="disableAll">{{ $t('disableAll') }}</MkButton>
<MkButton inline @click="enableAll">{{ $t('enableAll') }}</MkButton>
<div style="margin-bottom: 16px;"><b>{{ $ts.permission }}</b></div>
<MkButton inline @click="disableAll">{{ $ts.disableAll }}</MkButton>
<MkButton inline @click="enableAll">{{ $ts.enableAll }}</MkButton>
<MkSwitch v-for="kind in (initialPermissions || kinds)" :key="kind" v-model:value="permissions[kind]">{{ $t(`_permissions.${kind}`) }}</MkSwitch>
</div>
</XModalWindow>

View File

@ -48,7 +48,7 @@
</datalist>
<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="desc _caption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -35,7 +35,7 @@
</button>
</template>
<span v-if="_items.length === 0" class="none item">
<span>{{ $t('none') }}</span>
<span>{{ $ts.none }}</span>
</span>
</div>
</template>

View File

@ -6,7 +6,7 @@
</div>
<div class="more" v-show="more" key="_more_">
<MkButton class="button" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary>
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><MkLoading inline/></template>
</MkButton>
</div>

View File

@ -14,7 +14,7 @@
@blur="focused = false"
></textarea>
</div>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $t('save') }}</button>
<button class="save _textButton" v-if="save && changed" @click="() => { changed = false; save(); }">{{ $ts.save }}</button>
<div class="desc _caption"><slot name="desc"></slot></div>
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<div v-if="playerEnabled" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
<button class="disablePlayer" @click="playerEnabled = false" :title="$t('disablePlayer')"><Fa icon="times"/></button>
<button class="disablePlayer" @click="playerEnabled = false" :title="$ts.disablePlayer"><Fa icon="times"/></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 />
</div>
<div v-else-if="tweetId && tweetExpanded" class="twitter" ref="twitter">
@ -10,7 +10,7 @@
<transition name="zoom" mode="out-in">
<component :is="self ? 'MkA' : 'a'" :class="{ compact }" :[attr]="self ? url.substr(local.length) : url" rel="nofollow noopener" :target="target" :title="url" v-if="!fetching">
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url('${thumbnail}')`">
<button class="_button" v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enablePlayer')"><Fa :icon="faPlayCircle"/></button>
<button class="_button" v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$ts.enablePlayer"><Fa :icon="faPlayCircle"/></button>
</div>
<article>
<header>
@ -26,7 +26,7 @@
</transition>
<div class="expandTweet" v-if="tweetId">
<a @click="tweetExpanded = true">
<Fa :icon="faTwitter"/> {{ $t('expandTweet') }}
<Fa :icon="faTwitter"/> {{ $ts.expandTweet }}
</a>
</div>
</div>

View File

@ -10,17 +10,17 @@
<div class="mfm" v-if="user.description">
<Mfm :text="user.description" :author="user" :i="$i" :custom-emojis="user.emojis"/>
</div>
<span v-else style="opacity: 0.7;">{{ $t('noAccountDescription') }}</span>
<span v-else style="opacity: 0.7;">{{ $ts.noAccountDescription }}</span>
</div>
<div class="status">
<div>
<p>{{ $t('notes') }}</p><span>{{ user.notesCount }}</span>
<p>{{ $ts.notes }}</p><span>{{ user.notesCount }}</span>
</div>
<div>
<p>{{ $t('following') }}</p><span>{{ user.followingCount }}</span>
<p>{{ $ts.following }}</p><span>{{ user.followingCount }}</span>
</div>
<div>
<p>{{ $t('followers') }}</p><span>{{ user.followersCount }}</span>
<p>{{ $ts.followers }}</p><span>{{ user.followersCount }}</span>
</div>
</div>
<MkFollowButton class="koudoku-button" v-if="$i && user.id != $i.id" :user="user" mini/>

View File

@ -3,13 +3,13 @@
<div v-else class="efvhhmdq">
<div class="no-users" v-if="empty">
<p>{{ $t('noUsers') }}</p>
<p>{{ $ts.noUsers }}</p>
</div>
<div class="users">
<MkUserInfo class="user" v-for="user in users" :user="user" :key="user.id"/>
</div>
<button class="more" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :class="{ fetching: moreFetching }" v-show="more" :disabled="moreFetching">
<template v-if="moreFetching"><Fa icon="spinner" pulse fixed-width/></template>{{ moreFetching ? $t('loading') : $t('loadMore') }}
<template v-if="moreFetching"><Fa icon="spinner" pulse fixed-width/></template>{{ moreFetching ? $ts.loading : $ts.loadMore }}
</button>
</div>
</template>

View File

@ -13,13 +13,13 @@
</div>
<div class="status">
<div>
<p>{{ $t('notes') }}</p><span>{{ user.notesCount }}</span>
<p>{{ $ts.notes }}</p><span>{{ user.notesCount }}</span>
</div>
<div>
<p>{{ $t('following') }}</p><span>{{ user.followingCount }}</span>
<p>{{ $ts.following }}</p><span>{{ user.followingCount }}</span>
</div>
<div>
<p>{{ $t('followers') }}</p><span>{{ user.followersCount }}</span>
<p>{{ $ts.followers }}</p><span>{{ user.followersCount }}</span>
</div>
</div>
<MkFollowButton class="koudoku-button" v-if="$i && user.id != $i.id" :user="user" mini/>

View File

@ -7,11 +7,11 @@
@ok="ok()"
@closed="$emit('closed')"
>
<template #header>{{ $t('selectUser') }}</template>
<template #header>{{ $ts.selectUser }}</template>
<div class="tbhwbxda _section">
<div class="inputs">
<MkInput v-model:value="username" class="input" @update:value="search" ref="username"><span>{{ $t('username') }}</span><template #prefix>@</template></MkInput>
<MkInput v-model:value="host" class="input" @update:value="search"><span>{{ $t('host') }}</span><template #prefix>@</template></MkInput>
<MkInput v-model:value="username" class="input" @update:value="search" ref="username"><span>{{ $ts.username }}</span><template #prefix>@</template></MkInput>
<MkInput v-model:value="host" class="input" @update:value="search"><span>{{ $ts.host }}</span><template #prefix>@</template></MkInput>
</div>
</div>
<div class="tbhwbxda _section result" v-if="username != '' || host != ''" :class="{ hit: users.length > 0 }">
@ -25,7 +25,7 @@
</div>
</div>
<div v-else class="empty">
<span>{{ $t('noUsers') }}</span>
<span>{{ $ts.noUsers }}</span>
</div>
</div>
<div class="tbhwbxda _section recent" v-if="username == '' && host == ''">

View File

@ -15,11 +15,11 @@
</MkA>
</div>
<button class="more _button" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" v-show="more" :disabled="moreFetching">
<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
<template v-if="moreFetching"><Fa :icon="faSpinner" pulse fixed-width/></template>
</button>
<p class="empty" v-if="empty">{{ $t('noUsers') }}</p>
<p class="empty" v-if="empty">{{ $ts.noUsers }}</p>
<MkError v-if="error" @retry="init()"/>
</div>

View File

@ -4,37 +4,37 @@
<button class="_button" @click="choose('public')" :class="{ active: v == 'public' }" data-index="1" key="public">
<div><Fa :icon="faGlobe"/></div>
<div>
<span>{{ $t('_visibility.public') }}</span>
<span>{{ $t('_visibility.publicDescription') }}</span>
<span>{{ $ts._visibility.public }}</span>
<span>{{ $ts._visibility.publicDescription }}</span>
</div>
</button>
<button class="_button" @click="choose('home')" :class="{ active: v == 'home' }" data-index="2" key="home">
<div><Fa :icon="faHome"/></div>
<div>
<span>{{ $t('_visibility.home') }}</span>
<span>{{ $t('_visibility.homeDescription') }}</span>
<span>{{ $ts._visibility.home }}</span>
<span>{{ $ts._visibility.homeDescription }}</span>
</div>
</button>
<button class="_button" @click="choose('followers')" :class="{ active: v == 'followers' }" data-index="3" key="followers">
<div><Fa :icon="faUnlock"/></div>
<div>
<span>{{ $t('_visibility.followers') }}</span>
<span>{{ $t('_visibility.followersDescription') }}</span>
<span>{{ $ts._visibility.followers }}</span>
<span>{{ $ts._visibility.followersDescription }}</span>
</div>
</button>
<button :disabled="localOnly" class="_button" @click="choose('specified')" :class="{ active: v == 'specified' }" data-index="4" key="specified">
<div><Fa :icon="faEnvelope"/></div>
<div>
<span>{{ $t('_visibility.specified') }}</span>
<span>{{ $t('_visibility.specifiedDescription') }}</span>
<span>{{ $ts._visibility.specified }}</span>
<span>{{ $ts._visibility.specifiedDescription }}</span>
</div>
</button>
<div class="divider"></div>
<button class="_button localOnly" @click="localOnly = !localOnly" :class="{ active: localOnly }" data-index="5" key="localOnly">
<div><Fa :icon="faBiohazard"/></div>
<div>
<span>{{ $t('_visibility.localOnly') }}</span>
<span>{{ $t('_visibility.localOnlyDescription') }}</span>
<span>{{ $ts._visibility.localOnly }}</span>
<span>{{ $ts._visibility.localOnlyDescription }}</span>
</div>
<div><Fa :icon="localOnly ? faToggleOn : faToggleOff" :key="localOnly"/></div>
</button>