forked from FoundKeyGang/FoundKey
Merge branch 'master' into l10n_master
This commit is contained in:
commit
bc94878225
129 changed files with 1548 additions and 1373 deletions
|
@ -22,6 +22,7 @@
|
||||||
"globals": {
|
"globals": {
|
||||||
"ENV": true,
|
"ENV": true,
|
||||||
"VERSION": true,
|
"VERSION": true,
|
||||||
"API": true
|
"API": true,
|
||||||
|
"LANGS": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@
|
||||||
/build
|
/build
|
||||||
/built
|
/built
|
||||||
/data
|
/data
|
||||||
|
/.cache-loader
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
*.pem
|
*.pem
|
||||||
run.bat
|
run.bat
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|
||||||
|
branches:
|
||||||
|
except:
|
||||||
|
- l10n_master
|
||||||
|
|
||||||
language: node_js
|
language: node_js
|
||||||
|
|
||||||
node_js:
|
node_js:
|
||||||
|
|
BIN
assets/title-dark.svg
Normal file
BIN
assets/title-dark.svg
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -8,7 +8,8 @@ const { default: User } = require('../built/models/user');
|
||||||
const q = {
|
const q = {
|
||||||
'metadata._user.host': {
|
'metadata._user.host': {
|
||||||
$ne: null
|
$ne: null
|
||||||
}
|
},
|
||||||
|
'metadata.isMetaOnly': false
|
||||||
};
|
};
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
@ -56,8 +57,7 @@ async function main() {
|
||||||
|
|
||||||
DriveFile.update({ _id: file._id }, {
|
DriveFile.update({ _id: file._id }, {
|
||||||
$set: {
|
$set: {
|
||||||
'metadata.deletedAt': new Date(),
|
'metadata.isMetaOnly': true
|
||||||
'metadata.isExpired': true
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]).then(async () => {
|
]).then(async () => {
|
||||||
|
|
|
@ -43,13 +43,7 @@ Please install and setup these softwares:
|
||||||
|
|
||||||
*4.* Prepare configuration
|
*4.* Prepare configuration
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
1. Copy `example.yml` of `.config` directory
|
You need to generate config file via `npm run config` command.
|
||||||
2. Rename it to `default.yml`
|
|
||||||
3. Edit it
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Or you can generate config file via `npm run config` command.
|
|
||||||
|
|
||||||
*5.* Build Misskey
|
*5.* Build Misskey
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
|
@ -43,18 +43,14 @@ web-push generate-vapid-keys
|
||||||
|
|
||||||
*4.* 設定ファイルを用意する
|
*4.* 設定ファイルを用意する
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
1. `.config`ディレクトリ内の`example.yml`をコピー
|
`npm run config`コマンドを利用して、ガイドに従って情報を入力してください。
|
||||||
2. `default.yml`にリネーム
|
|
||||||
3. 編集する
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
または、`npm run config`コマンドを利用して、ガイドに従って情報を
|
|
||||||
入力して設定ファイルを生成することもできます。
|
|
||||||
|
|
||||||
*5.* Misskeyのビルド
|
*5.* Misskeyのビルド
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
1. `npm run build`
|
1. `npm install -g node-gyp`
|
||||||
|
2. `node-gyp configure`
|
||||||
|
3. `node-gyp build`
|
||||||
|
4. `npm run build`
|
||||||
|
|
||||||
*6.* 以上です!
|
*6.* 以上です!
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
|
@ -359,7 +359,7 @@ desktop/views/components/renote-form.vue:
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "Are you sure you want to renote this note?"
|
title: "Are you sure you want to renote this note?"
|
||||||
desktop/views/components/settings-window.vue:
|
desktop/views/components/settings-window.vue:
|
||||||
settings: "設定"
|
settings: "Settings"
|
||||||
desktop/views/components/settings.vue:
|
desktop/views/components/settings.vue:
|
||||||
profile: "Profile"
|
profile: "Profile"
|
||||||
notification: "Notification"
|
notification: "Notification"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
meta:
|
meta:
|
||||||
lang: "日本語"
|
lang: "Français"
|
||||||
divider: " "
|
divider: " "
|
||||||
common:
|
common:
|
||||||
misskey: "Partagez avec les autres en utilisant Misskey"
|
misskey: "Partagez avec les autres en utilisant Misskey"
|
||||||
|
|
119
locales/ja.yml
119
locales/ja.yml
|
@ -173,6 +173,16 @@ common/views/components/twitter-setting.vue:
|
||||||
common/views/components/uploader.vue:
|
common/views/components/uploader.vue:
|
||||||
waiting: "待機中"
|
waiting: "待機中"
|
||||||
|
|
||||||
|
common/views/components/visibility-chooser.vue:
|
||||||
|
public: "公開"
|
||||||
|
home: "ホーム"
|
||||||
|
home-desc: "ホームタイムラインにのみ公開"
|
||||||
|
followers: "フォロワー"
|
||||||
|
followers-desc: "自分のフォロワーにのみ公開"
|
||||||
|
specified: "ダイレクト"
|
||||||
|
specified-desc: "指定したユーザーにのみ公開"
|
||||||
|
private: "非公開"
|
||||||
|
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
|
@ -340,6 +350,14 @@ desktop/views/components/messaging-room-window.vue:
|
||||||
desktop/views/components/messaging-window.vue:
|
desktop/views/components/messaging-window.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
|
|
||||||
|
desktop/views/components/note-detail.vue:
|
||||||
|
more: "会話をもっと読み込む"
|
||||||
|
private: "(この投稿は非公開です)"
|
||||||
|
reposted-by: "{}がRenote"
|
||||||
|
location: "位置情報"
|
||||||
|
renote: "Renote"
|
||||||
|
add-reaction: "リアクション"
|
||||||
|
|
||||||
desktop/views/components/note-detail.sub.vue:
|
desktop/views/components/note-detail.sub.vue:
|
||||||
private: "(この投稿は非公開です)"
|
private: "(この投稿は非公開です)"
|
||||||
|
|
||||||
|
@ -399,6 +417,9 @@ desktop/views/components/renote-form.vue:
|
||||||
desktop/views/components/renote-form-window.vue:
|
desktop/views/components/renote-form-window.vue:
|
||||||
title: "この投稿をRenoteしますか?"
|
title: "この投稿をRenoteしますか?"
|
||||||
|
|
||||||
|
desktop/views/components/settings-window.vue:
|
||||||
|
settings: "設定"
|
||||||
|
|
||||||
desktop/views/components/settings.vue:
|
desktop/views/components/settings.vue:
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
notification: "通知"
|
notification: "通知"
|
||||||
|
@ -477,9 +498,6 @@ desktop/views/components/settings.vue:
|
||||||
advanced-settings: "高度な設定"
|
advanced-settings: "高度な設定"
|
||||||
debug-mode: "デバッグモードを有効にする"
|
debug-mode: "デバッグモードを有効にする"
|
||||||
debug-mode-desc: "この設定はブラウザに記憶されます。"
|
debug-mode-desc: "この設定はブラウザに記憶されます。"
|
||||||
use-raw-script: "生のスクリプトを読み込む"
|
|
||||||
use-raw-script-desc: "圧縮されていない「生の」スクリプトを使用します。サイズが大きいため、読み込みに時間がかかる場合があります。この設定はブラウザに記憶されます。"
|
|
||||||
source-info: "Misskeyはソースマップも提供しています。"
|
|
||||||
experimental: "実験的機能を有効にする"
|
experimental: "実験的機能を有効にする"
|
||||||
experimental-desc: "実験的機能を有効にするとMisskeyの動作が不安定になる可能性があります。この設定はブラウザに記憶されます。"
|
experimental-desc: "実験的機能を有効にするとMisskeyの動作が不安定になる可能性があります。この設定はブラウザに記憶されます。"
|
||||||
tools: "ツール"
|
tools: "ツール"
|
||||||
|
@ -535,6 +553,13 @@ desktop/views/components/settings.profile.vue:
|
||||||
description: "自己紹介"
|
description: "自己紹介"
|
||||||
birthday: "誕生日"
|
birthday: "誕生日"
|
||||||
save: "保存"
|
save: "保存"
|
||||||
|
is-bot: "このアカウントはBotです"
|
||||||
|
is-cat: "このアカウントはCatです"
|
||||||
|
|
||||||
|
desktop/views/components/sub-note-content.vue:
|
||||||
|
hidden: "(この投稿は非公開です)"
|
||||||
|
media: "つのメディア"
|
||||||
|
poll: "投票"
|
||||||
|
|
||||||
desktop/views/components/taskmanager.vue:
|
desktop/views/components/taskmanager.vue:
|
||||||
title: "タスクマネージャ"
|
title: "タスクマネージャ"
|
||||||
|
@ -583,6 +608,29 @@ desktop/views/components/users-list.vue:
|
||||||
load-more: "もっと"
|
load-more: "もっと"
|
||||||
fetching: "読み込んでいます"
|
fetching: "読み込んでいます"
|
||||||
|
|
||||||
|
desktop/views/components/users-list-item.vue:
|
||||||
|
followed: "フォローされています"
|
||||||
|
|
||||||
|
desktop/views/components/window.vue:
|
||||||
|
popout: "ポップアウト"
|
||||||
|
close: "閉じる"
|
||||||
|
|
||||||
|
desktop/views/pages/welcome.vue:
|
||||||
|
signin: "ログイン"
|
||||||
|
signup: "新規登録"
|
||||||
|
signin-button: "やってる"
|
||||||
|
signup-button: "やる"
|
||||||
|
timeline: "タイムライン"
|
||||||
|
|
||||||
|
desktop/views/pages/drive.vue:
|
||||||
|
title: "Misskey Drive"
|
||||||
|
|
||||||
|
desktop/views/pages/favorites.vue:
|
||||||
|
more: "さらに読み込む"
|
||||||
|
|
||||||
|
desktop/views/pages/home-customize.vue:
|
||||||
|
title: "ホームのカスタマイズ"
|
||||||
|
|
||||||
desktop/views/pages/note.vue:
|
desktop/views/pages/note.vue:
|
||||||
prev: "前の投稿"
|
prev: "前の投稿"
|
||||||
next: "次の投稿"
|
next: "次の投稿"
|
||||||
|
@ -593,6 +641,11 @@ desktop/views/pages/selectdrive.vue:
|
||||||
cancel: "キャンセル"
|
cancel: "キャンセル"
|
||||||
upload: "PCからドライブにファイルをアップロード"
|
upload: "PCからドライブにファイルをアップロード"
|
||||||
|
|
||||||
|
desktop/views/pages/user-list.users.vue:
|
||||||
|
users: "ユーザー"
|
||||||
|
add-user: "ユーザーを追加"
|
||||||
|
username: "ユーザー名"
|
||||||
|
|
||||||
desktop/views/pages/user/user.followers-you-know.vue:
|
desktop/views/pages/user/user.followers-you-know.vue:
|
||||||
title: "知り合いのフォロワー"
|
title: "知り合いのフォロワー"
|
||||||
loading: "読み込み中"
|
loading: "読み込み中"
|
||||||
|
@ -625,6 +678,12 @@ desktop/views/pages/user/user.profile.vue:
|
||||||
muted: "ミュートしています"
|
muted: "ミュートしています"
|
||||||
unmute: "ミュート解除"
|
unmute: "ミュート解除"
|
||||||
|
|
||||||
|
desktop/views/pages/user/user.timeline.vue:
|
||||||
|
default: "投稿"
|
||||||
|
with-replies: "投稿と返信"
|
||||||
|
with-media: "メディア"
|
||||||
|
empty: "このユーザーはまだ何も投稿していないようです。"
|
||||||
|
|
||||||
desktop/views/widgets/messaging.vue:
|
desktop/views/widgets/messaging.vue:
|
||||||
title: "メッセージ"
|
title: "メッセージ"
|
||||||
|
|
||||||
|
@ -642,6 +701,10 @@ desktop/views/widgets/post-form.vue:
|
||||||
note: "投稿"
|
note: "投稿"
|
||||||
placeholder: "いまどうしてる?"
|
placeholder: "いまどうしてる?"
|
||||||
|
|
||||||
|
desktop/views/widgets/profile.vue:
|
||||||
|
update-banner: "クリックでバナー編集"
|
||||||
|
update-avatar: "クリックでアバター編集"
|
||||||
|
|
||||||
desktop/views/widgets/trends.vue:
|
desktop/views/widgets/trends.vue:
|
||||||
title: "トレンド"
|
title: "トレンド"
|
||||||
refresh: "他を見る"
|
refresh: "他を見る"
|
||||||
|
@ -735,7 +798,9 @@ mobile/views/pages/following.vue:
|
||||||
following-of: "{}のフォロー"
|
following-of: "{}のフォロー"
|
||||||
|
|
||||||
mobile/views/pages/home.vue:
|
mobile/views/pages/home.vue:
|
||||||
timeline: "タイムライン"
|
home: "ホーム"
|
||||||
|
local: "ローカル"
|
||||||
|
global: "グローバル"
|
||||||
|
|
||||||
mobile/views/pages/messaging.vue:
|
mobile/views/pages/messaging.vue:
|
||||||
messaging: "メッセージ"
|
messaging: "メッセージ"
|
||||||
|
@ -753,20 +818,19 @@ mobile/views/pages/notifications.vue:
|
||||||
read-all: "すべての通知を既読にしますか?"
|
read-all: "すべての通知を既読にしますか?"
|
||||||
|
|
||||||
mobile/views/pages/settings/settings.profile.vue:
|
mobile/views/pages/settings/settings.profile.vue:
|
||||||
title: "プロフィール設定"
|
title: "プロフィール"
|
||||||
will-be-published: "これらのプロフィールは公開されます。"
|
|
||||||
name: "名前"
|
name: "名前"
|
||||||
|
account: "アカウント"
|
||||||
location: "場所"
|
location: "場所"
|
||||||
description: "自己紹介"
|
description: "自己紹介"
|
||||||
birthday: "誕生日"
|
birthday: "誕生日"
|
||||||
avatar: "アイコン"
|
avatar: "アイコン"
|
||||||
banner: "バナー"
|
banner: "バナー"
|
||||||
avatar-saved: "アイコンを保存しました"
|
is-cat: "このアカウントはCatです"
|
||||||
banner-saved: "バナーを保存しました"
|
|
||||||
set-avatar: "アイコンを選択する"
|
|
||||||
set-banner: "バナーを選択する"
|
|
||||||
save: "保存"
|
save: "保存"
|
||||||
saved: "プロフィールを保存しました"
|
saved: "プロフィールを保存しました"
|
||||||
|
uploading: "アップロード中"
|
||||||
|
upload-failed: "アップロードに失敗しました"
|
||||||
|
|
||||||
mobile/views/pages/search.vue:
|
mobile/views/pages/search.vue:
|
||||||
search: "検索"
|
search: "検索"
|
||||||
|
@ -777,9 +841,40 @@ mobile/views/pages/selectdrive.vue:
|
||||||
|
|
||||||
mobile/views/pages/settings.vue:
|
mobile/views/pages/settings.vue:
|
||||||
signed-in-as: "{}としてサインイン中"
|
signed-in-as: "{}としてサインイン中"
|
||||||
profile: "プロフィール"
|
lang: "言語"
|
||||||
|
lang-tip: "変更はページの再読み込み後に反映されます。"
|
||||||
|
recommended: "推奨"
|
||||||
|
auto: "自動"
|
||||||
|
specify-language: "言語を指定"
|
||||||
|
design: "デザインと表示"
|
||||||
|
dark-mode: "ダークモード"
|
||||||
|
i-am-under-limited-internet: "私は通信を制限されている"
|
||||||
|
circle-icons: "円形のアイコンを使用"
|
||||||
|
timeline: "タイムライン"
|
||||||
|
show-reply-target: "リプライ先を表示する"
|
||||||
|
show-my-renotes: "自分の行ったRenoteを表示する"
|
||||||
|
show-renoted-my-notes: "Renoteされた自分の投稿を表示する"
|
||||||
|
post-style: "投稿の表示スタイル"
|
||||||
|
post-style-standard: "標準"
|
||||||
|
post-style-smart: "スマート"
|
||||||
|
behavior: "動作"
|
||||||
|
fetch-on-scroll: "スクロールで自動読み込み"
|
||||||
|
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
||||||
|
load-raw-images: "添付された画像を高画質で表示する"
|
||||||
|
load-remote-media: "リモートサーバーのメディアを表示する"
|
||||||
twitter: "Twitter連携"
|
twitter: "Twitter連携"
|
||||||
signin-history: "サインイン履歴"
|
twitter-connect: "Twitterアカウントに接続する"
|
||||||
|
twitter-reconnect: "再接続する"
|
||||||
|
twitter-disconnect: "切断する"
|
||||||
|
update: "Misskey Update"
|
||||||
|
version: "バージョン:"
|
||||||
|
latest-version: "最新のバージョン:"
|
||||||
|
update-checking: "アップデートを確認中"
|
||||||
|
check-for-updates: "アップデートを確認"
|
||||||
|
no-updates: "利用可能な更新はありません"
|
||||||
|
no-updates-desc: "お使いのMisskeyは最新です。"
|
||||||
|
update-available: "新しいバージョンが利用可能です"
|
||||||
|
update-available-desc: "ページを再度読み込みすると更新が適用されます。"
|
||||||
settings: "設定"
|
settings: "設定"
|
||||||
signout: "サインアウト"
|
signout: "サインアウト"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
meta:
|
meta:
|
||||||
lang: "japoński"
|
lang: "język polski"
|
||||||
divider: " "
|
divider: " "
|
||||||
common:
|
common:
|
||||||
misskey: "Dziel się zawartością z innymi korzystając z Misskey."
|
misskey: "Dziel się zawartością z innymi korzystając z Misskey."
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
meta:
|
meta:
|
||||||
lang: "日本語"
|
lang: "Русский язык"
|
||||||
divider: " "
|
divider: " "
|
||||||
common:
|
common:
|
||||||
misskey: "Misskeyで皆と共有しよう。"
|
misskey: "Misskeyで皆と共有しよう。"
|
||||||
|
|
21
package.json
21
package.json
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "2.10.1",
|
"version": "2.17.0",
|
||||||
"clientVersion": "1.0.5407",
|
"clientVersion": "1.0.5731",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
"@types/mongodb": "3.0.18",
|
"@types/mongodb": "3.0.18",
|
||||||
"@types/monk": "6.0.0",
|
"@types/monk": "6.0.0",
|
||||||
"@types/ms": "0.7.30",
|
"@types/ms": "0.7.30",
|
||||||
"@types/node": "10.1.0",
|
"@types/node": "10.1.2",
|
||||||
"@types/nopt": "3.0.29",
|
"@types/nopt": "3.0.29",
|
||||||
"@types/parse5": "3.0.0",
|
"@types/parse5": "3.0.0",
|
||||||
"@types/pug": "2.0.4",
|
"@types/pug": "2.0.4",
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
"@types/speakeasy": "2.0.2",
|
"@types/speakeasy": "2.0.2",
|
||||||
"@types/tmp": "0.0.33",
|
"@types/tmp": "0.0.33",
|
||||||
"@types/uuid": "3.4.3",
|
"@types/uuid": "3.4.3",
|
||||||
"@types/webpack": "4.1.7",
|
"@types/webpack": "4.4.0",
|
||||||
"@types/webpack-stream": "3.2.10",
|
"@types/webpack-stream": "3.2.10",
|
||||||
"@types/websocket": "0.0.39",
|
"@types/websocket": "0.0.39",
|
||||||
"@types/ws": "5.1.1",
|
"@types/ws": "5.1.1",
|
||||||
|
@ -98,8 +98,8 @@
|
||||||
"deepcopy": "0.6.3",
|
"deepcopy": "0.6.3",
|
||||||
"diskusage": "0.2.4",
|
"diskusage": "0.2.4",
|
||||||
"dompurify": "1.0.4",
|
"dompurify": "1.0.4",
|
||||||
"elasticsearch": "14.2.2",
|
"elasticsearch": "15.0.0",
|
||||||
"element-ui": "2.3.8",
|
"element-ui": "2.3.9",
|
||||||
"emojilib": "2.2.12",
|
"emojilib": "2.2.12",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"eslint": "4.19.1",
|
"eslint": "4.19.1",
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
"gulp-typescript": "4.0.2",
|
"gulp-typescript": "4.0.2",
|
||||||
"gulp-uglify": "3.0.0",
|
"gulp-uglify": "3.0.0",
|
||||||
"gulp-util": "3.0.8",
|
"gulp-util": "3.0.8",
|
||||||
"hard-source-webpack-plugin": "0.6.7",
|
"hard-source-webpack-plugin": "0.6.9",
|
||||||
"highlight.js": "9.12.0",
|
"highlight.js": "9.12.0",
|
||||||
"html-minifier": "3.5.15",
|
"html-minifier": "3.5.15",
|
||||||
"http-signature": "1.2.0",
|
"http-signature": "1.2.0",
|
||||||
|
@ -146,11 +146,11 @@
|
||||||
"koa-slow": "2.1.0",
|
"koa-slow": "2.1.0",
|
||||||
"koa-views": "6.1.4",
|
"koa-views": "6.1.4",
|
||||||
"kue": "0.11.6",
|
"kue": "0.11.6",
|
||||||
"license-checker": "19.0.0",
|
"license-checker": "20.0.0",
|
||||||
"loader-utils": "1.1.0",
|
"loader-utils": "1.1.0",
|
||||||
"mecab-async": "0.1.2",
|
"mecab-async": "0.1.2",
|
||||||
"mkdirp": "0.5.1",
|
"mkdirp": "0.5.1",
|
||||||
"mocha": "5.1.1",
|
"mocha": "5.2.0",
|
||||||
"moji": "0.5.1",
|
"moji": "0.5.1",
|
||||||
"mongodb": "3.0.8",
|
"mongodb": "3.0.8",
|
||||||
"monk": "6.0.6",
|
"monk": "6.0.6",
|
||||||
|
@ -205,12 +205,13 @@
|
||||||
"vue-cropperjs": "2.2.0",
|
"vue-cropperjs": "2.2.0",
|
||||||
"vue-js-modal": "1.3.13",
|
"vue-js-modal": "1.3.13",
|
||||||
"vue-json-tree-view": "2.1.4",
|
"vue-json-tree-view": "2.1.4",
|
||||||
"vue-loader": "15.0.11",
|
"vue-loader": "15.1.0",
|
||||||
"vue-material": "^1.0.0-beta-10.2",
|
"vue-material": "^1.0.0-beta-10.2",
|
||||||
"vue-router": "3.0.1",
|
"vue-router": "3.0.1",
|
||||||
"vue-template-compiler": "2.5.16",
|
"vue-template-compiler": "2.5.16",
|
||||||
"vuedraggable": "2.16.0",
|
"vuedraggable": "2.16.0",
|
||||||
"vuex": "3.0.1",
|
"vuex": "3.0.1",
|
||||||
|
"vuex-persistedstate": "^2.5.4",
|
||||||
"web-push": "3.3.1",
|
"web-push": "3.3.1",
|
||||||
"webfinger.js": "2.6.6",
|
"webfinger.js": "2.6.6",
|
||||||
"webpack": "4.8.3",
|
"webpack": "4.8.3",
|
||||||
|
|
|
@ -7,7 +7,7 @@ import locale from '../../locales';
|
||||||
export default class Replacer {
|
export default class Replacer {
|
||||||
private lang: string;
|
private lang: string;
|
||||||
|
|
||||||
public pattern = /%i18n:([a-z0-9_\-\.\/\|\!]+?)%/g;
|
public pattern = /%i18n:([a-z0-9_\-\.\/\|]+?)%/g;
|
||||||
|
|
||||||
constructor(lang: string) {
|
constructor(lang: string) {
|
||||||
this.lang = lang;
|
this.lang = lang;
|
||||||
|
@ -56,11 +56,6 @@ export default class Replacer {
|
||||||
public replacement(match, key) {
|
public replacement(match, key) {
|
||||||
let path = null;
|
let path = null;
|
||||||
|
|
||||||
const shouldEscape = key[0] == '!';
|
|
||||||
if (shouldEscape) {
|
|
||||||
key = key.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.indexOf('|') != -1) {
|
if (key.indexOf('|') != -1) {
|
||||||
path = key.split('|')[0];
|
path = key.split('|')[0];
|
||||||
key = key.split('|')[1];
|
key = key.split('|')[1];
|
||||||
|
@ -68,8 +63,6 @@ export default class Replacer {
|
||||||
|
|
||||||
const txt = this.get(path, key);
|
const txt = this.get(path, key);
|
||||||
|
|
||||||
return shouldEscape
|
return txt.replace(/'/g, '\\x27').replace(/"/g, '\\x22');
|
||||||
? txt.replace(/'/g, '\\x27').replace(/"/g, '\\x22')
|
|
||||||
: txt.replace(/"/g, '"');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,11 @@ html
|
||||||
cursor progress !important
|
cursor progress !important
|
||||||
|
|
||||||
body
|
body
|
||||||
|
// for md
|
||||||
|
font-size 16px !important
|
||||||
|
line-height initial !important
|
||||||
|
letter-spacing initial !important
|
||||||
|
|
||||||
overflow-wrap break-word
|
overflow-wrap break-word
|
||||||
|
|
||||||
#error
|
#error
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#region Load settings
|
||||||
|
let settings = null;
|
||||||
|
const vuex = localStorage.getItem('vuex');
|
||||||
|
if (vuex) {
|
||||||
|
settings = JSON.parse(vuex);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
// Get the current url information
|
// Get the current url information
|
||||||
const url = new URL(location.href);
|
const url = new URL(location.href);
|
||||||
|
|
||||||
|
@ -29,11 +37,16 @@
|
||||||
if (url.pathname == '/auth') app = 'auth';
|
if (url.pathname == '/auth') app = 'auth';
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
// Detect the user language
|
//#region Detect the user language
|
||||||
// Note: The default language is Japanese
|
|
||||||
let lang = navigator.language.split('-')[0];
|
let lang = navigator.language.split('-')[0];
|
||||||
|
|
||||||
|
// The default language is English
|
||||||
if (!LANGS.includes(lang)) lang = 'en';
|
if (!LANGS.includes(lang)) lang = 'en';
|
||||||
if (localStorage.getItem('lang')) lang = localStorage.getItem('lang');
|
|
||||||
|
if (settings) {
|
||||||
|
if (settings.device.lang) lang = settings.device.lang;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
// Detect the user agent
|
// Detect the user agent
|
||||||
const ua = navigator.userAgent.toLowerCase();
|
const ua = navigator.userAgent.toLowerCase();
|
||||||
|
@ -61,20 +74,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dark/Light
|
// Dark/Light
|
||||||
if (localStorage.getItem('darkmode') == 'true') {
|
if (settings) {
|
||||||
|
if (settings.device.darkmode) {
|
||||||
document.documentElement.setAttribute('data-darkmode', 'true');
|
document.documentElement.setAttribute('data-darkmode', 'true');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Script version
|
// Script version
|
||||||
const ver = localStorage.getItem('v') || VERSION;
|
const ver = localStorage.getItem('v') || VERSION;
|
||||||
|
|
||||||
// Whether in debug mode
|
|
||||||
const isDebug = localStorage.getItem('debug') == 'true';
|
|
||||||
|
|
||||||
// Whether use raw version script
|
|
||||||
const raw = (localStorage.getItem('useRawScript') == 'true' && isDebug)
|
|
||||||
|| ENV != 'production';
|
|
||||||
|
|
||||||
// Get salt query
|
// Get salt query
|
||||||
const salt = localStorage.getItem('salt')
|
const salt = localStorage.getItem('salt')
|
||||||
? '?salt=' + localStorage.getItem('salt')
|
? '?salt=' + localStorage.getItem('salt')
|
||||||
|
@ -84,7 +92,7 @@
|
||||||
// Note: 'async' make it possible to load the script asyncly.
|
// Note: 'async' make it possible to load the script asyncly.
|
||||||
// 'defer' make it possible to run the script when the dom loaded.
|
// 'defer' make it possible to run the script when the dom loaded.
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.setAttribute('src', `/assets/${app}.${ver}.${lang}.${raw ? 'raw' : 'min'}.js${salt}`);
|
script.setAttribute('src', `/assets/${app}.${ver}.${lang}.js${salt}`);
|
||||||
script.setAttribute('async', 'true');
|
script.setAttribute('async', 'true');
|
||||||
script.setAttribute('defer', 'true');
|
script.setAttribute('defer', 'true');
|
||||||
head.appendChild(script);
|
head.appendChild(script);
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default async function(mios: MiOS, force = false, silent = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
alert('%i18n:!common.update-available%'.replace('{newer}', newer).replace('{current}', current));
|
alert('%i18n:common.update-available%'.replace('{newer}', newer).replace('{current}', current));
|
||||||
}
|
}
|
||||||
|
|
||||||
return newer;
|
return newer;
|
||||||
|
|
|
@ -62,7 +62,7 @@ export class HomeStream extends Stream {
|
||||||
// トークンが再生成されたとき
|
// トークンが再生成されたとき
|
||||||
// このままではMisskeyが利用できないので強制的にサインアウトさせる
|
// このままではMisskeyが利用できないので強制的にサインアウトさせる
|
||||||
this.on('my_token_regenerated', () => {
|
this.on('my_token_regenerated', () => {
|
||||||
alert('%i18n:!common.my-token-regenerated%');
|
alert('%i18n:common.my-token-regenerated%');
|
||||||
os.signout();
|
os.signout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,17 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
lightmode(): boolean {
|
||||||
|
return this.$store.state.device.lightmode;
|
||||||
|
},
|
||||||
style(): any {
|
style(): any {
|
||||||
return {
|
return {
|
||||||
backgroundColor: this.user.avatarColor && this.user.avatarColor.length == 3 ? `rgb(${ this.user.avatarColor.join(',') })` : null,
|
backgroundColor: this.lightmode
|
||||||
backgroundImage: `url(${ this.user.avatarUrl }?thumbnail)`,
|
? `rgb(${ this.user.avatarColor.slice(0, 3).join(',') })`
|
||||||
|
: this.user.avatarColor && this.user.avatarColor.length == 3
|
||||||
|
? `rgb(${ this.user.avatarColor.join(',') })`
|
||||||
|
: null,
|
||||||
|
backgroundImage: this.lightmode ? null : `url(${ this.user.avatarUrl }?thumbnail)`,
|
||||||
borderRadius: (this as any).clientSettings.circleIcons ? '100%' : null
|
borderRadius: (this as any).clientSettings.circleIcons ? '100%' : null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,21 @@
|
||||||
<template v-if="network">%fa:check%</template>
|
<template v-if="network">%fa:check%</template>
|
||||||
<template v-if="!network">%fa:times%</template>
|
<template v-if="!network">%fa:times%</template>
|
||||||
</template>
|
</template>
|
||||||
{{ network == null ? '%i18n:!@checking-network%' : '%i18n:!@network%' }}<mk-ellipsis v-if="network == null"/>
|
{{ network == null ? '%i18n:@checking-network%' : '%i18n:@network%' }}<mk-ellipsis v-if="network == null"/>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="network == true" :data-wip="internet == null">
|
<p v-if="network == true" :data-wip="internet == null">
|
||||||
<template v-if="internet != null">
|
<template v-if="internet != null">
|
||||||
<template v-if="internet">%fa:check%</template>
|
<template v-if="internet">%fa:check%</template>
|
||||||
<template v-if="!internet">%fa:times%</template>
|
<template v-if="!internet">%fa:times%</template>
|
||||||
</template>
|
</template>
|
||||||
{{ internet == null ? '%i18n:!@checking-internet%' : '%i18n:!@internet%' }}<mk-ellipsis v-if="internet == null"/>
|
{{ internet == null ? '%i18n:@checking-internet%' : '%i18n:@internet%' }}<mk-ellipsis v-if="internet == null"/>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="internet == true" :data-wip="server == null">
|
<p v-if="internet == true" :data-wip="server == null">
|
||||||
<template v-if="server != null">
|
<template v-if="server != null">
|
||||||
<template v-if="server">%fa:check%</template>
|
<template v-if="server">%fa:check%</template>
|
||||||
<template v-if="!server">%fa:times%</template>
|
<template v-if="!server">%fa:times%</template>
|
||||||
</template>
|
</template>
|
||||||
{{ server == null ? '%i18n:!@checking-server%' : '%i18n:!@server%' }}<mk-ellipsis v-if="server == null"/>
|
{{ server == null ? '%i18n:@checking-server%' : '%i18n:@server%' }}<mk-ellipsis v-if="server == null"/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="!end">%i18n:@finding%<mk-ellipsis/></p>
|
<p v-if="!end">%i18n:@finding%<mk-ellipsis/></p>
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<img src="data:image/jpeg;base64,%base64:/assets/error.jpg%" alt=""/>
|
<img src="data:image/jpeg;base64,%base64:/assets/error.jpg%" alt=""/>
|
||||||
<h1>%i18n:@title%</h1>
|
<h1>%i18n:@title%</h1>
|
||||||
<p class="text">
|
<p class="text">
|
||||||
<span>{{ '%i18n:!@description%'.substr(0, '%i18n:!@description%'.indexOf('{')) }}</span>
|
<span>{{ '%i18n:@description%'.substr(0, '%i18n:@description%'.indexOf('{')) }}</span>
|
||||||
<a @click="reload">{{ '%i18n:!@description%'.match(/\{(.+?)\}/)[1] }}</a>
|
<a @click="reload">{{ '%i18n:@description%'.match(/\{(.+?)\}/)[1] }}</a>
|
||||||
<span>{{ '%i18n:!@description%'.substr('%i18n:!@description%'.indexOf('}') + 1) }}</span>
|
<span>{{ '%i18n:@description%'.substr('%i18n:@description%'.indexOf('}') + 1) }}</span>
|
||||||
</p>
|
</p>
|
||||||
<button v-if="!troubleshooting" @click="troubleshooting = true">%i18n:@troubleshoot%</button>
|
<button v-if="!troubleshooting" @click="troubleshooting = true">%i18n:@troubleshoot%</button>
|
||||||
<x-troubleshooter v-if="troubleshooting"/>
|
<x-troubleshooter v-if="troubleshooting"/>
|
||||||
|
@ -28,7 +28,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
document.title = 'Oops!';
|
document.title = 'Oops!';
|
||||||
document.documentElement.style.background = '#f8f8f8';
|
document.documentElement.style.setProperty('background', '#f8f8f8', 'important');
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
reload() {
|
reload() {
|
||||||
|
|
|
@ -197,7 +197,7 @@ export default Vue.extend({
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@import '~const.styl'
|
@import '~const.styl'
|
||||||
|
|
||||||
.mk-messaging-form
|
root(isDark)
|
||||||
> textarea
|
> textarea
|
||||||
cursor auto
|
cursor auto
|
||||||
display block
|
display block
|
||||||
|
@ -209,10 +209,10 @@ export default Vue.extend({
|
||||||
padding 8px
|
padding 8px
|
||||||
resize none
|
resize none
|
||||||
font-size 1em
|
font-size 1em
|
||||||
color #000
|
color isDark ? #fff : #000
|
||||||
outline none
|
outline none
|
||||||
border none
|
border none
|
||||||
border-top solid 1px #eee
|
border-top solid 1px isDark ? #4b5056 : #eee
|
||||||
border-radius 0
|
border-radius 0
|
||||||
box-shadow none
|
box-shadow none
|
||||||
background transparent
|
background transparent
|
||||||
|
@ -302,4 +302,10 @@ export default Vue.extend({
|
||||||
input[type=file]
|
input[type=file]
|
||||||
display none
|
display none
|
||||||
|
|
||||||
|
.mk-messaging-form[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.mk-messaging-form:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -59,8 +59,10 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.message
|
@import '~const.styl'
|
||||||
$me-balloon-color = #23A7B6
|
|
||||||
|
root(isDark)
|
||||||
|
$me-balloon-color = $theme-color
|
||||||
|
|
||||||
padding 10px 12px 10px 12px
|
padding 10px 12px 10px 12px
|
||||||
background-color transparent
|
background-color transparent
|
||||||
|
@ -126,7 +128,7 @@ export default Vue.extend({
|
||||||
bottom -4px
|
bottom -4px
|
||||||
left -12px
|
left -12px
|
||||||
margin 0
|
margin 0
|
||||||
color rgba(#000, 0.5)
|
color isDark ? rgba(#fff, 0.5) : rgba(#000, 0.5)
|
||||||
font-size 11px
|
font-size 11px
|
||||||
|
|
||||||
> .content
|
> .content
|
||||||
|
@ -187,7 +189,7 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
margin 2px 0 0 0
|
margin 2px 0 0 0
|
||||||
font-size 10px
|
font-size 10px
|
||||||
color rgba(#000, 0.4)
|
color isDark ? rgba(#fff, 0.4) : rgba(#000, 0.4)
|
||||||
|
|
||||||
> [data-fa]
|
> [data-fa]
|
||||||
margin-left 4px
|
margin-left 4px
|
||||||
|
@ -200,8 +202,9 @@ export default Vue.extend({
|
||||||
padding-left 66px
|
padding-left 66px
|
||||||
|
|
||||||
> .balloon
|
> .balloon
|
||||||
|
$color = isDark ? #2d3338 : #eee
|
||||||
float left
|
float left
|
||||||
background #eee
|
background $color
|
||||||
|
|
||||||
&[data-no-text]
|
&[data-no-text]
|
||||||
background transparent
|
background transparent
|
||||||
|
@ -209,10 +212,15 @@ export default Vue.extend({
|
||||||
&:not([data-no-text]):before
|
&:not([data-no-text]):before
|
||||||
left -14px
|
left -14px
|
||||||
border-top solid 8px transparent
|
border-top solid 8px transparent
|
||||||
border-right solid 8px #eee
|
border-right solid 8px $color
|
||||||
border-bottom solid 8px transparent
|
border-bottom solid 8px transparent
|
||||||
border-left solid 8px transparent
|
border-left solid 8px transparent
|
||||||
|
|
||||||
|
> .content
|
||||||
|
> .text
|
||||||
|
if isDark
|
||||||
|
color #fff
|
||||||
|
|
||||||
> footer
|
> footer
|
||||||
text-align left
|
text-align left
|
||||||
|
|
||||||
|
@ -241,7 +249,7 @@ export default Vue.extend({
|
||||||
> .content
|
> .content
|
||||||
|
|
||||||
> p.is-deleted
|
> p.is-deleted
|
||||||
color rgba(255, 255, 255, 0.5)
|
color rgba(#fff, 0.5)
|
||||||
|
|
||||||
> .text >>>
|
> .text >>>
|
||||||
&, *
|
&, *
|
||||||
|
@ -254,4 +262,10 @@ export default Vue.extend({
|
||||||
> .baloon
|
> .baloon
|
||||||
opacity 0.5
|
opacity 0.5
|
||||||
|
|
||||||
|
.message[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.message:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<p class="empty" v-if="!init && messages.length == 0">%fa:info-circle%%i18n:@empty%</p>
|
<p class="empty" v-if="!init && messages.length == 0">%fa:info-circle%%i18n:@empty%</p>
|
||||||
<p class="no-history" v-if="!init && messages.length > 0 && !existMoreMessages">%fa:flag%%i18n:@no-history%</p>
|
<p class="no-history" v-if="!init && messages.length > 0 && !existMoreMessages">%fa:flag%%i18n:@no-history%</p>
|
||||||
<button class="more" :class="{ fetching: fetchingMoreMessages }" v-if="existMoreMessages" @click="fetchMoreMessages" :disabled="fetchingMoreMessages">
|
<button class="more" :class="{ fetching: fetchingMoreMessages }" v-if="existMoreMessages" @click="fetchMoreMessages" :disabled="fetchingMoreMessages">
|
||||||
<template v-if="fetchingMoreMessages">%fa:spinner .pulse .fw%</template>{{ fetchingMoreMessages ? '%i18n:!common.loading%' : '%i18n:!@more%' }}
|
<template v-if="fetchingMoreMessages">%fa:spinner .pulse .fw%</template>{{ fetchingMoreMessages ? '%i18n:common.loading%' : '%i18n:@more%' }}
|
||||||
</button>
|
</button>
|
||||||
<template v-for="(message, i) in _messages">
|
<template v-for="(message, i) in _messages">
|
||||||
<x-message :message="message" :key="message.id"/>
|
<x-message :message="message" :key="message.id"/>
|
||||||
|
@ -18,7 +18,11 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div ref="notifications" class="notifications"></div>
|
<transition name="fade">
|
||||||
|
<div class="new-message" v-show="showIndicator">
|
||||||
|
<button @click="onIndicatorClick">%fa:arrow-circle-down%%i18n:@new-message%</button>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
<x-form :user="user" ref="form"/>
|
<x-form :user="user" ref="form"/>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,7 +49,9 @@ export default Vue.extend({
|
||||||
fetchingMoreMessages: false,
|
fetchingMoreMessages: false,
|
||||||
messages: [],
|
messages: [],
|
||||||
existMoreMessages: false,
|
existMoreMessages: false,
|
||||||
connection: null
|
connection: null,
|
||||||
|
showIndicator: false,
|
||||||
|
timer: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -149,9 +155,9 @@ export default Vue.extend({
|
||||||
|
|
||||||
onMessage(message) {
|
onMessage(message) {
|
||||||
// サウンドを再生する
|
// サウンドを再生する
|
||||||
if ((this as any).os.isEnableSounds) {
|
if (this.$store.state.device.enableSounds) {
|
||||||
const sound = new Audio(`${url}/assets/message.mp3`);
|
const sound = new Audio(`${url}/assets/message.mp3`);
|
||||||
sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 0.5;
|
sound.volume = this.$store.state.device.soundVolume;
|
||||||
sound.play();
|
sound.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +178,7 @@ export default Vue.extend({
|
||||||
});
|
});
|
||||||
} else if (message.userId != (this as any).os.i.id) {
|
} else if (message.userId != (this as any).os.i.id) {
|
||||||
// Notify
|
// Notify
|
||||||
this.notify('%i18n:!@new-message%');
|
this.notifyNewMessage();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -205,18 +211,18 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
notify(message) {
|
onIndicatorClick() {
|
||||||
const n = document.createElement('p') as any;
|
this.showIndicator = false;
|
||||||
n.innerHTML = '%fa:arrow-circle-down%' + message;
|
|
||||||
n.onclick = () => {
|
|
||||||
this.scrollToBottom();
|
this.scrollToBottom();
|
||||||
n.parentNode.removeChild(n);
|
},
|
||||||
};
|
|
||||||
(this.$refs.notifications as any).appendChild(n);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
notifyNewMessage() {
|
||||||
n.style.opacity = 0;
|
this.showIndicator = true;
|
||||||
setTimeout(() => n.parentNode.removeChild(n), 1000);
|
|
||||||
|
if (this.timer) clearTimeout(this.timer);
|
||||||
|
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.showIndicator = false;
|
||||||
}, 4000);
|
}, 4000);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -238,11 +244,12 @@ export default Vue.extend({
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@import '~const.styl'
|
@import '~const.styl'
|
||||||
|
|
||||||
.mk-messaging-room
|
root(isDark)
|
||||||
display flex
|
display flex
|
||||||
flex 1
|
flex 1
|
||||||
flex-direction column
|
flex-direction column
|
||||||
height 100%
|
height 100%
|
||||||
|
background isDark ? #191b22 : #fff
|
||||||
|
|
||||||
> .stream
|
> .stream
|
||||||
width 100%
|
width 100%
|
||||||
|
@ -256,7 +263,7 @@ export default Vue.extend({
|
||||||
padding 16px 8px 8px 8px
|
padding 16px 8px 8px 8px
|
||||||
text-align center
|
text-align center
|
||||||
font-size 0.8em
|
font-size 0.8em
|
||||||
color rgba(#000, 0.4)
|
color rgba(isDark ? #fff : #000, 0.4)
|
||||||
|
|
||||||
[data-fa]
|
[data-fa]
|
||||||
margin-right 4px
|
margin-right 4px
|
||||||
|
@ -267,7 +274,7 @@ export default Vue.extend({
|
||||||
padding 16px 8px 8px 8px
|
padding 16px 8px 8px 8px
|
||||||
text-align center
|
text-align center
|
||||||
font-size 0.8em
|
font-size 0.8em
|
||||||
color rgba(#000, 0.4)
|
color rgba(isDark ? #fff : #000, 0.4)
|
||||||
|
|
||||||
[data-fa]
|
[data-fa]
|
||||||
margin-right 4px
|
margin-right 4px
|
||||||
|
@ -278,7 +285,7 @@ export default Vue.extend({
|
||||||
padding 16px
|
padding 16px
|
||||||
text-align center
|
text-align center
|
||||||
font-size 0.8em
|
font-size 0.8em
|
||||||
color rgba(#000, 0.4)
|
color rgba(isDark ? #fff : #000, 0.4)
|
||||||
|
|
||||||
[data-fa]
|
[data-fa]
|
||||||
margin-right 4px
|
margin-right 4px
|
||||||
|
@ -322,7 +329,7 @@ export default Vue.extend({
|
||||||
left 0
|
left 0
|
||||||
right 0
|
right 0
|
||||||
margin 0 auto
|
margin 0 auto
|
||||||
background rgba(#000, 0.1)
|
background rgba(isDark ? #fff : #000, 0.1)
|
||||||
|
|
||||||
> span
|
> span
|
||||||
display inline-block
|
display inline-block
|
||||||
|
@ -330,8 +337,8 @@ export default Vue.extend({
|
||||||
padding 0 16px
|
padding 0 16px
|
||||||
//font-weight bold
|
//font-weight bold
|
||||||
line-height 32px
|
line-height 32px
|
||||||
color rgba(#000, 0.3)
|
color rgba(isDark ? #fff : #000, 0.3)
|
||||||
background #fff
|
background isDark ? #191b22 : #fff
|
||||||
|
|
||||||
> footer
|
> footer
|
||||||
position -webkit-sticky
|
position -webkit-sticky
|
||||||
|
@ -342,30 +349,32 @@ export default Vue.extend({
|
||||||
max-width 600px
|
max-width 600px
|
||||||
margin 0 auto
|
margin 0 auto
|
||||||
padding 0
|
padding 0
|
||||||
background rgba(255, 255, 255, 0.95)
|
background rgba(isDark ? #282c37 : #fff, 0.95)
|
||||||
background-clip content-box
|
background-clip content-box
|
||||||
|
|
||||||
> .notifications
|
> .new-message
|
||||||
position absolute
|
position absolute
|
||||||
top -48px
|
top -48px
|
||||||
width 100%
|
width 100%
|
||||||
padding 8px 0
|
padding 8px 0
|
||||||
text-align center
|
text-align center
|
||||||
|
|
||||||
&:empty
|
> button
|
||||||
display none
|
|
||||||
|
|
||||||
> p
|
|
||||||
display inline-block
|
display inline-block
|
||||||
margin 0
|
margin 0
|
||||||
padding 0 12px 0 28px
|
padding 0 12px 0 30px
|
||||||
cursor pointer
|
cursor pointer
|
||||||
line-height 32px
|
line-height 32px
|
||||||
font-size 12px
|
font-size 12px
|
||||||
color $theme-color-foreground
|
color $theme-color-foreground
|
||||||
background $theme-color
|
background $theme-color
|
||||||
border-radius 16px
|
border-radius 16px
|
||||||
transition opacity 1s ease
|
|
||||||
|
&:hover
|
||||||
|
background lighten($theme-color, 10%)
|
||||||
|
|
||||||
|
&:active
|
||||||
|
background darken($theme-color, 10%)
|
||||||
|
|
||||||
> [data-fa]
|
> [data-fa]
|
||||||
position absolute
|
position absolute
|
||||||
|
@ -374,4 +383,17 @@ export default Vue.extend({
|
||||||
line-height 32px
|
line-height 32px
|
||||||
font-size 16px
|
font-size 16px
|
||||||
|
|
||||||
|
.fade-enter-active, .fade-leave-active
|
||||||
|
transition opacity 0.1s
|
||||||
|
|
||||||
|
.fade-enter, .fade-leave-to
|
||||||
|
transition opacity 0.5s
|
||||||
|
opacity 0
|
||||||
|
|
||||||
|
.mk-messaging-room[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.mk-messaging-room:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -162,9 +162,9 @@ export default Vue.extend({
|
||||||
this.o.put(this.myColor, pos);
|
this.o.put(this.myColor, pos);
|
||||||
|
|
||||||
// サウンドを再生する
|
// サウンドを再生する
|
||||||
if ((this as any).os.isEnableSounds) {
|
if (this.$store.state.device.enableSounds) {
|
||||||
const sound = new Audio(`${url}/assets/othello-put-me.mp3`);
|
const sound = new Audio(`${url}/assets/othello-put-me.mp3`);
|
||||||
sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 0.5;
|
sound.volume = this.$store.state.device.soundVolume;
|
||||||
sound.play();
|
sound.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,9 +186,9 @@ export default Vue.extend({
|
||||||
this.$forceUpdate();
|
this.$forceUpdate();
|
||||||
|
|
||||||
// サウンドを再生する
|
// サウンドを再生する
|
||||||
if ((this as any).os.isEnableSounds && x.color != this.myColor) {
|
if (this.$store.state.device.enableSounds && x.color != this.myColor) {
|
||||||
const sound = new Audio(`${url}/assets/othello-put-you.mp3`);
|
const sound = new Audio(`${url}/assets/othello-put-you.mp3`);
|
||||||
sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 0.5;
|
sound.volume = this.$store.state.device.soundVolume;
|
||||||
sound.play();
|
sound.play();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</p>
|
</p>
|
||||||
<ul ref="choices">
|
<ul ref="choices">
|
||||||
<li v-for="(choice, i) in choices">
|
<li v-for="(choice, i) in choices">
|
||||||
<input :value="choice" @input="onInput(i, $event)" :placeholder="'%i18n:!@choice-n%'.replace('{}', i + 1)">
|
<input :value="choice" @input="onInput(i, $event)" :placeholder="'%i18n:@choice-n%'.replace('{}', i + 1)">
|
||||||
<button @click="remove(i)" title="%i18n:@remove%">
|
<button @click="remove(i)" title="%i18n:@remove%">
|
||||||
%fa:times%
|
%fa:times%
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-poll" :data-is-voted="isVoted">
|
<div class="mk-poll" :data-is-voted="isVoted">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="choice in poll.choices" :key="choice.id" @click="vote(choice.id)" :class="{ voted: choice.voted }" :title="!isVoted ? '%i18n:!@vote-to%'.replace('{}', choice.text) : ''">
|
<li v-for="choice in poll.choices" :key="choice.id" @click="vote(choice.id)" :class="{ voted: choice.voted }" :title="!isVoted ? '%i18n:@vote-to%'.replace('{}', choice.text) : ''">
|
||||||
<div class="backdrop" :style="{ 'width': (showResult ? (choice.votes / total * 100) : 0) + '%' }"></div>
|
<div class="backdrop" :style="{ 'width': (showResult ? (choice.votes / total * 100) : 0) + '%' }"></div>
|
||||||
<span>
|
<span>
|
||||||
<template v-if="choice.isVoted">%fa:check%</template>
|
<template v-if="choice.isVoted">%fa:check%</template>
|
||||||
<span>{{ choice.text }}</span>
|
<span>{{ choice.text }}</span>
|
||||||
<span class="votes" v-if="showResult">({{ '%i18n:!@vote-count%'.replace('{}', choice.votes) }})</span>
|
<span class="votes" v-if="showResult">({{ '%i18n:@vote-count%'.replace('{}', choice.votes) }})</span>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p v-if="total > 0">
|
<p v-if="total > 0">
|
||||||
<span>{{ '%i18n:!@total-users%'.replace('{}', total) }}</span>
|
<span>{{ '%i18n:@total-users%'.replace('{}', total) }}</span>
|
||||||
<span>・</span>
|
<span>・</span>
|
||||||
<a v-if="!isVoted" @click="toggleShowResult">{{ showResult ? '%i18n:!@vote%' : '%i18n:!@show-result%' }}</a>
|
<a v-if="!isVoted" @click="toggleShowResult">{{ showResult ? '%i18n:@vote%' : '%i18n:@show-result%' }}</a>
|
||||||
<span v-if="isVoted">%i18n:@voted%</span>
|
<span v-if="isVoted">%i18n:@voted%</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import * as anime from 'animejs';
|
import * as anime from 'animejs';
|
||||||
|
|
||||||
const placeholder = '%i18n:!@choose-reaction%';
|
const placeholder = '%i18n:@choose-reaction%';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['note', 'source', 'compact', 'cb'],
|
props: ['note', 'source', 'compact', 'cb'],
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<label class="token" v-if="user && user.twoFactorEnabled">
|
<label class="token" v-if="user && user.twoFactorEnabled">
|
||||||
<input v-model="token" type="number" placeholder="%i18n:@token%" required/>%fa:lock%
|
<input v-model="token" type="number" placeholder="%i18n:@token%" required/>%fa:lock%
|
||||||
</label>
|
</label>
|
||||||
<button type="submit" :disabled="signing">{{ signing ? '%i18n:!@signing-in%' : '%i18n:!@signin%' }}</button>
|
<button type="submit" :disabled="signing">{{ signing ? '%i18n:@signing-in%' : '%i18n:@signin%' }}</button>
|
||||||
もしくは <a :href="`${apiUrl}/signin/twitter`">Twitterでログイン</a>
|
もしくは <a :href="`${apiUrl}/signin/twitter`">Twitterでログイン</a>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -127,7 +127,7 @@ export default Vue.extend({
|
||||||
location.href = '/';
|
location.href = '/';
|
||||||
});
|
});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
alert('%i18n:!@some-error%');
|
alert('%i18n:@some-error%');
|
||||||
|
|
||||||
(window as any).grecaptcha.reset();
|
(window as any).grecaptcha.reset();
|
||||||
this.recaptchaed = false;
|
this.recaptchaed = false;
|
||||||
|
|
|
@ -44,16 +44,16 @@ export default Vue.extend({
|
||||||
const time = this._time;
|
const time = this._time;
|
||||||
const ago = (this.now.getTime() - time.getTime()) / 1000/*ms*/;
|
const ago = (this.now.getTime() - time.getTime()) / 1000/*ms*/;
|
||||||
return (
|
return (
|
||||||
ago >= 31536000 ? '%i18n:!common.time.years_ago%' .replace('{}', (~~(ago / 31536000)).toString()) :
|
ago >= 31536000 ? '%i18n:common.time.years_ago%' .replace('{}', (~~(ago / 31536000)).toString()) :
|
||||||
ago >= 2592000 ? '%i18n:!common.time.months_ago%' .replace('{}', (~~(ago / 2592000)).toString()) :
|
ago >= 2592000 ? '%i18n:common.time.months_ago%' .replace('{}', (~~(ago / 2592000)).toString()) :
|
||||||
ago >= 604800 ? '%i18n:!common.time.weeks_ago%' .replace('{}', (~~(ago / 604800)).toString()) :
|
ago >= 604800 ? '%i18n:common.time.weeks_ago%' .replace('{}', (~~(ago / 604800)).toString()) :
|
||||||
ago >= 86400 ? '%i18n:!common.time.days_ago%' .replace('{}', (~~(ago / 86400)).toString()) :
|
ago >= 86400 ? '%i18n:common.time.days_ago%' .replace('{}', (~~(ago / 86400)).toString()) :
|
||||||
ago >= 3600 ? '%i18n:!common.time.hours_ago%' .replace('{}', (~~(ago / 3600)).toString()) :
|
ago >= 3600 ? '%i18n:common.time.hours_ago%' .replace('{}', (~~(ago / 3600)).toString()) :
|
||||||
ago >= 60 ? '%i18n:!common.time.minutes_ago%'.replace('{}', (~~(ago / 60)).toString()) :
|
ago >= 60 ? '%i18n:common.time.minutes_ago%'.replace('{}', (~~(ago / 60)).toString()) :
|
||||||
ago >= 10 ? '%i18n:!common.time.seconds_ago%'.replace('{}', (~~(ago % 60)).toString()) :
|
ago >= 10 ? '%i18n:common.time.seconds_ago%'.replace('{}', (~~(ago % 60)).toString()) :
|
||||||
ago >= 0 ? '%i18n:!common.time.just_now%' :
|
ago >= 0 ? '%i18n:common.time.just_now%' :
|
||||||
ago < 0 ? '%i18n:!common.time.future%' :
|
ago < 0 ? '%i18n:common.time.future%' :
|
||||||
'%i18n:!common.time.unknown%');
|
'%i18n:common.time.unknown%');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<p>%i18n:@description%<a :href="`${docsUrl}/link-to-twitter`" target="_blank">%i18n:@detail%</a></p>
|
<p>%i18n:@description%<a :href="`${docsUrl}/link-to-twitter`" target="_blank">%i18n:@detail%</a></p>
|
||||||
<p class="account" v-if="os.i.twitter" :title="`Twitter ID: ${os.i.twitter.userId}`">%i18n:@connected-to%: <a :href="`https://twitter.com/${os.i.twitter.screenName}`" target="_blank">@{{ os.i.twitter.screenName }}</a></p>
|
<p class="account" v-if="os.i.twitter" :title="`Twitter ID: ${os.i.twitter.userId}`">%i18n:@connected-to%: <a :href="`https://twitter.com/${os.i.twitter.screenName}`" target="_blank">@{{ os.i.twitter.screenName }}</a></p>
|
||||||
<p>
|
<p>
|
||||||
<a :href="`${apiUrl}/connect/twitter`" target="_blank" @click.prevent="connect">{{ os.i.twitter ? '%i18n:!@reconnect%' : '%i18n:!@connect%' }}</a>
|
<a :href="`${apiUrl}/connect/twitter`" target="_blank" @click.prevent="connect">{{ os.i.twitter ? '%i18n:@reconnect%' : '%i18n:@connect%' }}</a>
|
||||||
<span v-if="os.i.twitter"> or </span>
|
<span v-if="os.i.twitter"> or </span>
|
||||||
<a :href="`${apiUrl}/disconnect/twitter`" target="_blank" v-if="os.i.twitter" @click.prevent="disconnect">%i18n:@disconnect%</a>
|
<a :href="`${apiUrl}/disconnect/twitter`" target="_blank" v-if="os.i.twitter" @click.prevent="disconnect">%i18n:@disconnect%</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -5,34 +5,34 @@
|
||||||
<div @click="choose('public')" :class="{ active: v == 'public' }">
|
<div @click="choose('public')" :class="{ active: v == 'public' }">
|
||||||
<div>%fa:globe%</div>
|
<div>%fa:globe%</div>
|
||||||
<div>
|
<div>
|
||||||
<span>公開</span>
|
<span>%i18n:@public%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div @click="choose('home')" :class="{ active: v == 'home' }">
|
<div @click="choose('home')" :class="{ active: v == 'home' }">
|
||||||
<div>%fa:home%</div>
|
<div>%fa:home%</div>
|
||||||
<div>
|
<div>
|
||||||
<span>ホーム</span>
|
<span>%i18n:@home%</span>
|
||||||
<span>ホームタイムラインにのみ公開</span>
|
<span>%i18n:@home-desc%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div @click="choose('followers')" :class="{ active: v == 'followers' }">
|
<div @click="choose('followers')" :class="{ active: v == 'followers' }">
|
||||||
<div>%fa:unlock%</div>
|
<div>%fa:unlock%</div>
|
||||||
<div>
|
<div>
|
||||||
<span>フォロワー</span>
|
<span>%i18n:@followers%</span>
|
||||||
<span>自分のフォロワーにのみ公開</span>
|
<span>%i18n:@followers-desc%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div @click="choose('specified')" :class="{ active: v == 'specified' }">
|
<div @click="choose('specified')" :class="{ active: v == 'specified' }">
|
||||||
<div>%fa:envelope%</div>
|
<div>%fa:envelope%</div>
|
||||||
<div>
|
<div>
|
||||||
<span>ダイレクト</span>
|
<span>%i18n:@specified%</span>
|
||||||
<span>指定したユーザーにのみ公開</span>
|
<span>%i18n:@specified-desc%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div @click="choose('private')" :class="{ active: v == 'private' }">
|
<div @click="choose('private')" :class="{ active: v == 'private' }">
|
||||||
<div>%fa:lock%</div>
|
<div>%fa:lock%</div>
|
||||||
<div>
|
<div>
|
||||||
<span>非公開</span>
|
<span>%i18n:@private%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -37,6 +37,7 @@ export default Vue.extend({
|
||||||
fetch(cb?) {
|
fetch(cb?) {
|
||||||
this.fetching = true;
|
this.fetching = true;
|
||||||
(this as any).api('notes', {
|
(this as any).api('notes', {
|
||||||
|
local: true,
|
||||||
reply: false,
|
reply: false,
|
||||||
renote: false,
|
renote: false,
|
||||||
media: false,
|
media: false,
|
||||||
|
@ -52,15 +53,15 @@ export default Vue.extend({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-welcome-timeline
|
root(isDark)
|
||||||
background #fff
|
background isDark ? #282C37 : #fff
|
||||||
|
|
||||||
> div
|
> div
|
||||||
padding 16px
|
padding 16px
|
||||||
overflow-wrap break-word
|
overflow-wrap break-word
|
||||||
font-size .9em
|
font-size .9em
|
||||||
color #4C4C4C
|
color isDark ? #fff : #4C4C4C
|
||||||
border-bottom 1px solid rgba(#000, 0.05)
|
border-bottom 1px solid isDark ? rgba(#000, 0.1) : rgba(#000, 0.05)
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
content ""
|
content ""
|
||||||
|
@ -95,17 +96,23 @@ export default Vue.extend({
|
||||||
overflow hidden
|
overflow hidden
|
||||||
font-weight bold
|
font-weight bold
|
||||||
text-overflow ellipsis
|
text-overflow ellipsis
|
||||||
color #627079
|
color isDark ? #fff : #627079
|
||||||
|
|
||||||
> .username
|
> .username
|
||||||
margin 0 .5em 0 0
|
margin 0 .5em 0 0
|
||||||
color #ccc
|
color isDark ? #606984 : #ccc
|
||||||
|
|
||||||
> .info
|
> .info
|
||||||
margin-left auto
|
margin-left auto
|
||||||
font-size 0.9em
|
font-size 0.9em
|
||||||
|
|
||||||
> .created-at
|
> .created-at
|
||||||
color #c0c0c0
|
color isDark ? #606984 : #c0c0c0
|
||||||
|
|
||||||
|
.mk-welcome-timeline[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.mk-welcome-timeline:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="fetching" v-if="fetching">%i18n:@fetching%<mk-ellipsis/></p>
|
<p class="fetching" v-if="fetching">%i18n:@fetching%<mk-ellipsis/></p>
|
||||||
<h1 v-if="!fetching">{{ broadcasts.length == 0 ? '%i18n:!@no-broadcasts%' : broadcasts[i].title }}</h1>
|
<h1 v-if="!fetching">{{ broadcasts.length == 0 ? '%i18n:@no-broadcasts%' : broadcasts[i].title }}</h1>
|
||||||
<p v-if="!fetching">
|
<p v-if="!fetching">
|
||||||
<span v-if="broadcasts.length != 0" v-html="broadcasts[i].text"></span>
|
<span v-if="broadcasts.length != 0" v-html="broadcasts[i].text"></span>
|
||||||
<template v-if="broadcasts.length == 0">%i18n:@have-a-nice-day%</template>
|
<template v-if="broadcasts.length == 0">%i18n:@have-a-nice-day%</template>
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<article>
|
<article>
|
||||||
<h1>%fa:heart%%i18n:@title%</h1>
|
<h1>%fa:heart%%i18n:@title%</h1>
|
||||||
<p>
|
<p>
|
||||||
{{ '%i18n:!@text%'.substr(0, '%i18n:!@text%'.indexOf('{')) }}
|
{{ '%i18n:@text%'.substr(0, '%i18n:@text%'.indexOf('{')) }}
|
||||||
<a href="https://syuilo.com">@syuilo</a>
|
<a href="https://syuilo.com">@syuilo</a>
|
||||||
{{ '%i18n:!@text%'.substr('%i18n:!@text%'.indexOf('}') + 1) }}
|
{{ '%i18n:@text%'.substr('%i18n:@text%'.indexOf('}') + 1) }}
|
||||||
</p>
|
</p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,6 +8,7 @@ declare const _STATS_URL_: string;
|
||||||
declare const _STATUS_URL_: string;
|
declare const _STATUS_URL_: string;
|
||||||
declare const _DEV_URL_: string;
|
declare const _DEV_URL_: string;
|
||||||
declare const _LANG_: string;
|
declare const _LANG_: string;
|
||||||
|
declare const _LANGS_: string;
|
||||||
declare const _RECAPTCHA_SITEKEY_: string;
|
declare const _RECAPTCHA_SITEKEY_: string;
|
||||||
declare const _SW_PUBLICKEY_: string;
|
declare const _SW_PUBLICKEY_: string;
|
||||||
declare const _THEME_COLOR_: string;
|
declare const _THEME_COLOR_: string;
|
||||||
|
@ -27,6 +28,7 @@ export const statsUrl = _STATS_URL_;
|
||||||
export const statusUrl = _STATUS_URL_;
|
export const statusUrl = _STATUS_URL_;
|
||||||
export const devUrl = _DEV_URL_;
|
export const devUrl = _DEV_URL_;
|
||||||
export const lang = _LANG_;
|
export const lang = _LANG_;
|
||||||
|
export const langs = _LANGS_;
|
||||||
export const recaptchaSitekey = _RECAPTCHA_SITEKEY_;
|
export const recaptchaSitekey = _RECAPTCHA_SITEKEY_;
|
||||||
export const swPublickey = _SW_PUBLICKEY_;
|
export const swPublickey = _SW_PUBLICKEY_;
|
||||||
export const themeColor = _THEME_COLOR_;
|
export const themeColor = _THEME_COLOR_;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="mk-calendar" :data-melt="design == 4 || design == 5">
|
<div class="mk-calendar" :data-melt="design == 4 || design == 5">
|
||||||
<template v-if="design == 0 || design == 1">
|
<template v-if="design == 0 || design == 1">
|
||||||
<button @click="prev" title="%i18n:@prev%">%fa:chevron-circle-left%</button>
|
<button @click="prev" title="%i18n:@prev%">%fa:chevron-circle-left%</button>
|
||||||
<p class="title">{{ '%i18n:!@title%'.replace('{1}', year).replace('{2}', month) }}</p>
|
<p class="title">{{ '%i18n:@title%'.replace('{1}', year).replace('{2}', month) }}</p>
|
||||||
<button @click="next" title="%i18n:@next%">%fa:chevron-circle-right%</button>
|
<button @click="next" title="%i18n:@next%">%fa:chevron-circle-right%</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
:data-is-out-of-range="isOutOfRange(i + 1)"
|
:data-is-out-of-range="isOutOfRange(i + 1)"
|
||||||
:data-is-donichi="isDonichi(i + 1)"
|
:data-is-donichi="isDonichi(i + 1)"
|
||||||
@click="go(i + 1)"
|
@click="go(i + 1)"
|
||||||
:title="isOutOfRange(i + 1) ? null : '%i18n:!@go%'"
|
:title="isOutOfRange(i + 1) ? null : '%i18n:@go%'"
|
||||||
>
|
>
|
||||||
<div>{{ i + 1 }}</div>
|
<div>{{ i + 1 }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -58,13 +58,13 @@ export default Vue.extend({
|
||||||
month: new Date().getMonth() + 1,
|
month: new Date().getMonth() + 1,
|
||||||
selected: new Date(),
|
selected: new Date(),
|
||||||
weekdayText: [
|
weekdayText: [
|
||||||
'%i18n:!common.weekday-short.sunday%',
|
'%i18n:common.weekday-short.sunday%',
|
||||||
'%i18n:!common.weekday-short.monday%',
|
'%i18n:common.weekday-short.monday%',
|
||||||
'%i18n:!common.weekday-short.tuesday%',
|
'%i18n:common.weekday-short.tuesday%',
|
||||||
'%i18n:!common.weekday-short.wednesday%',
|
'%i18n:common.weekday-short.wednesday%',
|
||||||
'%i18n:!common.weekday-short.thursday%',
|
'%i18n:common.weekday-short.thursday%',
|
||||||
'%i18n:!common.weekday-short.friday%',
|
'%i18n:common.weekday-short.friday%',
|
||||||
'%i18n:!common.weekday-short.saturday%'
|
'%i18n:common.weekday-short.saturday%'
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -64,46 +64,46 @@ export default Vue.extend({
|
||||||
this.isContextmenuShowing = true;
|
this.isContextmenuShowing = true;
|
||||||
contextmenu(e, [{
|
contextmenu(e, [{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.rename%',
|
text: '%i18n:@contextmenu.rename%',
|
||||||
icon: '%fa:i-cursor%',
|
icon: '%fa:i-cursor%',
|
||||||
onClick: this.rename
|
onClick: this.rename
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.copy-url%',
|
text: '%i18n:@contextmenu.copy-url%',
|
||||||
icon: '%fa:link%',
|
icon: '%fa:link%',
|
||||||
onClick: this.copyUrl
|
onClick: this.copyUrl
|
||||||
}, {
|
}, {
|
||||||
type: 'link',
|
type: 'link',
|
||||||
href: `${this.file.url}?download`,
|
href: `${this.file.url}?download`,
|
||||||
text: '%i18n:!@contextmenu.download%',
|
text: '%i18n:@contextmenu.download%',
|
||||||
icon: '%fa:download%',
|
icon: '%fa:download%',
|
||||||
}, {
|
}, {
|
||||||
type: 'divider',
|
type: 'divider',
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!common.delete%',
|
text: '%i18n:common.delete%',
|
||||||
icon: '%fa:R trash-alt%',
|
icon: '%fa:R trash-alt%',
|
||||||
onClick: this.deleteFile
|
onClick: this.deleteFile
|
||||||
}, {
|
}, {
|
||||||
type: 'divider',
|
type: 'divider',
|
||||||
}, {
|
}, {
|
||||||
type: 'nest',
|
type: 'nest',
|
||||||
text: '%i18n:!@contextmenu.else-files%',
|
text: '%i18n:@contextmenu.else-files%',
|
||||||
menu: [{
|
menu: [{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.set-as-avatar%',
|
text: '%i18n:@contextmenu.set-as-avatar%',
|
||||||
onClick: this.setAsAvatar
|
onClick: this.setAsAvatar
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.set-as-banner%',
|
text: '%i18n:@contextmenu.set-as-banner%',
|
||||||
onClick: this.setAsBanner
|
onClick: this.setAsBanner
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
type: 'nest',
|
type: 'nest',
|
||||||
text: '%i18n:!@contextmenu.open-in-app%',
|
text: '%i18n:@contextmenu.open-in-app%',
|
||||||
menu: [{
|
menu: [{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.add-app%...',
|
text: '%i18n:@contextmenu.add-app%...',
|
||||||
onClick: this.addApp
|
onClick: this.addApp
|
||||||
}]
|
}]
|
||||||
}], {
|
}], {
|
||||||
|
@ -141,8 +141,8 @@ export default Vue.extend({
|
||||||
|
|
||||||
rename() {
|
rename() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@contextmenu.rename-file%',
|
title: '%i18n:@contextmenu.rename-file%',
|
||||||
placeholder: '%i18n:!@contextmenu.input-new-file-name%',
|
placeholder: '%i18n:@contextmenu.input-new-file-name%',
|
||||||
default: this.file.name,
|
default: this.file.name,
|
||||||
allowEmpty: false
|
allowEmpty: false
|
||||||
}).then(name => {
|
}).then(name => {
|
||||||
|
@ -157,9 +157,9 @@ export default Vue.extend({
|
||||||
copyToClipboard(this.file.url);
|
copyToClipboard(this.file.url);
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: '%fa:check%%i18n:@contextmenu.copied%',
|
title: '%fa:check%%i18n:@contextmenu.copied%',
|
||||||
text: '%i18n:!@contextmenu.copied-url-to-clipboard%',
|
text: '%i18n:@contextmenu.copied-url-to-clipboard%',
|
||||||
actions: [{
|
actions: [{
|
||||||
text: '%i18n:!common.ok%'
|
text: '%i18n:common.ok%'
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -54,26 +54,26 @@ export default Vue.extend({
|
||||||
this.isContextmenuShowing = true;
|
this.isContextmenuShowing = true;
|
||||||
contextmenu(e, [{
|
contextmenu(e, [{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.move-to-this-folder%',
|
text: '%i18n:@contextmenu.move-to-this-folder%',
|
||||||
icon: '%fa:arrow-right%',
|
icon: '%fa:arrow-right%',
|
||||||
onClick: this.go
|
onClick: this.go
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.show-in-new-window%',
|
text: '%i18n:@contextmenu.show-in-new-window%',
|
||||||
icon: '%fa:R window-restore%',
|
icon: '%fa:R window-restore%',
|
||||||
onClick: this.newWindow
|
onClick: this.newWindow
|
||||||
}, {
|
}, {
|
||||||
type: 'divider',
|
type: 'divider',
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.rename%',
|
text: '%i18n:@contextmenu.rename%',
|
||||||
icon: '%fa:i-cursor%',
|
icon: '%fa:i-cursor%',
|
||||||
onClick: this.rename
|
onClick: this.rename
|
||||||
}, {
|
}, {
|
||||||
type: 'divider',
|
type: 'divider',
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!common.delete%',
|
text: '%i18n:common.delete%',
|
||||||
icon: '%fa:R trash-alt%',
|
icon: '%fa:R trash-alt%',
|
||||||
onClick: this.deleteFolder
|
onClick: this.deleteFolder
|
||||||
}], {
|
}], {
|
||||||
|
@ -159,15 +159,15 @@ export default Vue.extend({
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case 'detected-circular-definition':
|
case 'detected-circular-definition':
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: '%fa:exclamation-triangle%%i18n:!@unable-to-process%',
|
title: '%fa:exclamation-triangle%%i18n:@unable-to-process%',
|
||||||
text: '%i18n:!@circular-reference-detected%',
|
text: '%i18n:@circular-reference-detected%',
|
||||||
actions: [{
|
actions: [{
|
||||||
text: '%i18n:!common.ok%'
|
text: '%i18n:common.ok%'
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
alert('%i18n:!@unhandled-error% ' + err);
|
alert('%i18n:@unhandled-error% ' + err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -199,8 +199,8 @@ export default Vue.extend({
|
||||||
|
|
||||||
rename() {
|
rename() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@contextmenu.rename-folder%',
|
title: '%i18n:@contextmenu.rename-folder%',
|
||||||
placeholder: '%i18n:!@contextmenu.input-new-folder-name%',
|
placeholder: '%i18n:@contextmenu.input-new-folder-name%',
|
||||||
default: this.folder.name
|
default: this.folder.name
|
||||||
}).then(name => {
|
}).then(name => {
|
||||||
(this as any).api('drive/folders/update', {
|
(this as any).api('drive/folders/update', {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
@drop.stop="onDrop"
|
@drop.stop="onDrop"
|
||||||
>
|
>
|
||||||
<template v-if="folder == null">%fa:cloud%</template>
|
<template v-if="folder == null">%fa:cloud%</template>
|
||||||
<span>{{ folder == null ? '%i18n:!@drive%' : folder.name }}</span>
|
<span>{{ folder == null ? '%i18n:@drive%' : folder.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -138,17 +138,17 @@ export default Vue.extend({
|
||||||
onContextmenu(e) {
|
onContextmenu(e) {
|
||||||
contextmenu(e, [{
|
contextmenu(e, [{
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.create-folder%',
|
text: '%i18n:@contextmenu.create-folder%',
|
||||||
icon: '%fa:R folder%',
|
icon: '%fa:R folder%',
|
||||||
onClick: this.createFolder
|
onClick: this.createFolder
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.upload%',
|
text: '%i18n:@contextmenu.upload%',
|
||||||
icon: '%fa:upload%',
|
icon: '%fa:upload%',
|
||||||
onClick: this.selectLocalFile
|
onClick: this.selectLocalFile
|
||||||
}, {
|
}, {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
text: '%i18n:!@contextmenu.url-upload%',
|
text: '%i18n:@contextmenu.url-upload%',
|
||||||
icon: '%fa:cloud-upload-alt%',
|
icon: '%fa:cloud-upload-alt%',
|
||||||
onClick: this.urlUpload
|
onClick: this.urlUpload
|
||||||
}]);
|
}]);
|
||||||
|
@ -306,15 +306,15 @@ export default Vue.extend({
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case 'detected-circular-definition':
|
case 'detected-circular-definition':
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: '%fa:exclamation-triangle%%i18n:!@unable-to-process%',
|
title: '%fa:exclamation-triangle%%i18n:@unable-to-process%',
|
||||||
text: '%i18n:!@circular-reference-detected%',
|
text: '%i18n:@circular-reference-detected%',
|
||||||
actions: [{
|
actions: [{
|
||||||
text: '%i18n:!common.ok%'
|
text: '%i18n:common.ok%'
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
alert('%i18n:!@unhandled-error% ' + err);
|
alert('%i18n:@unhandled-error% ' + err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -327,8 +327,8 @@ export default Vue.extend({
|
||||||
|
|
||||||
urlUpload() {
|
urlUpload() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@url-upload%',
|
title: '%i18n:@url-upload%',
|
||||||
placeholder: '%i18n:!@url-of-file%'
|
placeholder: '%i18n:@url-of-file%'
|
||||||
}).then(url => {
|
}).then(url => {
|
||||||
(this as any).api('drive/files/upload_from_url', {
|
(this as any).api('drive/files/upload_from_url', {
|
||||||
url: url,
|
url: url,
|
||||||
|
@ -337,9 +337,9 @@ export default Vue.extend({
|
||||||
|
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: '%fa:check%%i18n:@url-upload-requested%',
|
title: '%fa:check%%i18n:@url-upload-requested%',
|
||||||
text: '%i18n:!@may-take-time%',
|
text: '%i18n:@may-take-time%',
|
||||||
actions: [{
|
actions: [{
|
||||||
text: '%i18n:!common.ok%'
|
text: '%i18n:common.ok%'
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -347,8 +347,8 @@ export default Vue.extend({
|
||||||
|
|
||||||
createFolder() {
|
createFolder() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@create-folder%',
|
title: '%i18n:@create-folder%',
|
||||||
placeholder: '%i18n:!@folder-name%'
|
placeholder: '%i18n:@folder-name%'
|
||||||
}).then(name => {
|
}).then(name => {
|
||||||
(this as any).api('drive/folders/create', {
|
(this as any).api('drive/folders/create', {
|
||||||
name: name,
|
name: name,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<mk-window width="400px" height="550px" @closed="$destroy">
|
<mk-window width="400px" height="550px" @closed="$destroy">
|
||||||
<span slot="header" :class="$style.header">
|
<span slot="header" :class="$style.header">
|
||||||
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt=""/>%i18n:!@followers%.replace('{}', {{ user | userName }})
|
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt=""/>{{ '%i18n:@followers%'.replace('{}', name) }}
|
||||||
</span>
|
</span>
|
||||||
<mk-followers :user="user"/>
|
<mk-followers :user="user"/>
|
||||||
</mk-window>
|
</mk-window>
|
||||||
|
@ -11,7 +11,12 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['user']
|
props: ['user'],
|
||||||
|
computed: {
|
||||||
|
name(): string {
|
||||||
|
return Vue.filter('userName')(this.user);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<mk-window width="400px" height="550px" @closed="$destroy">
|
<mk-window width="400px" height="550px" @closed="$destroy">
|
||||||
<span slot="header" :class="$style.header">
|
<span slot="header" :class="$style.header">
|
||||||
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt=""/>%i18n:!@following%.replace('{}', {{ user | userName }})
|
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt=""/>{{ '%i18n:@following%'.replace('{}', name) }}
|
||||||
</span>
|
</span>
|
||||||
<mk-following :user="user"/>
|
<mk-following :user="user"/>
|
||||||
</mk-window>
|
</mk-window>
|
||||||
|
@ -11,7 +11,12 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
props: ['user']
|
props: ['user'],
|
||||||
|
computed: {
|
||||||
|
name(): string {
|
||||||
|
return Vue.filter('userName')(this.user);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
home(): any[] {
|
home(): any[] {
|
||||||
return this.$store.state.settings.data.home;
|
return this.$store.state.settings.home;
|
||||||
},
|
},
|
||||||
left(): any[] {
|
left(): any[] {
|
||||||
return this.home.filter(w => w.place == 'left');
|
return this.home.filter(w => w.place == 'left');
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
<div class="mk-note-detail" :title="title">
|
<div class="mk-note-detail" :title="title">
|
||||||
<button
|
<button
|
||||||
class="read-more"
|
class="read-more"
|
||||||
v-if="p.reply && p.reply.replyId && context.length == 0"
|
v-if="p.reply && p.reply.replyId && conversation.length == 0"
|
||||||
title="会話をもっと読み込む"
|
title="%i18n:@more%"
|
||||||
@click="fetchContext"
|
@click="fetchConversation"
|
||||||
:disabled="contextFetching"
|
:disabled="conversationFetching"
|
||||||
>
|
>
|
||||||
<template v-if="!contextFetching">%fa:ellipsis-v%</template>
|
<template v-if="!conversationFetching">%fa:ellipsis-v%</template>
|
||||||
<template v-if="contextFetching">%fa:spinner .pulse%</template>
|
<template v-if="conversationFetching">%fa:spinner .pulse%</template>
|
||||||
</button>
|
</button>
|
||||||
<div class="context">
|
<div class="conversation">
|
||||||
<x-sub v-for="note in context" :key="note.id" :note="note"/>
|
<x-sub v-for="note in conversation" :key="note.id" :note="note"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="reply-to" v-if="p.reply">
|
<div class="reply-to" v-if="p.reply">
|
||||||
<x-sub :note="p.reply"/>
|
<x-sub :note="p.reply"/>
|
||||||
|
@ -21,7 +21,10 @@
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
%fa:retweet%
|
%fa:retweet%
|
||||||
<router-link class="name" :href="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :href="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
がRenote
|
<span>{{ '%i18n:@reposted-by%'.substr(0, '%i18n:@reposted-by%'.indexOf('{')) }}</span>
|
||||||
|
<a class="name" :href="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</a>
|
||||||
|
<span>{{ '%i18n:@reposted-by%'.substr('%i18n:@reposted-by%'.indexOf('}') + 1) }}</span>
|
||||||
|
<mk-time :time="note.createdAt"/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article>
|
||||||
|
@ -35,7 +38,7 @@
|
||||||
</header>
|
</header>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<span v-if="p.isHidden" style="opacity: 0.5">(この投稿は非公開です)</span>
|
<span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span>
|
||||||
<mk-note-html v-if="p.text" :text="p.text" :i="os.i"/>
|
<mk-note-html v-if="p.text" :text="p.text" :i="os.i"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="media" v-if="p.media.length > 0">
|
<div class="media" v-if="p.media.length > 0">
|
||||||
|
@ -46,7 +49,7 @@
|
||||||
<div class="tags" v-if="p.tags && p.tags.length > 0">
|
<div class="tags" v-if="p.tags && p.tags.length > 0">
|
||||||
<router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
|
<router-link v-for="tag in p.tags" :key="tag" :to="`/search?q=#${tag}`">{{ tag }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% 位置情報</a>
|
<a class="location" v-if="p.geo" :href="`http://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank">%fa:map-marker-alt% %i18n:@location%</a>
|
||||||
<div class="map" v-if="p.geo" ref="map"></div>
|
<div class="map" v-if="p.geo" ref="map"></div>
|
||||||
<div class="renote" v-if="p.renote">
|
<div class="renote" v-if="p.renote">
|
||||||
<mk-note-preview :note="p.renote"/>
|
<mk-note-preview :note="p.renote"/>
|
||||||
|
@ -54,15 +57,15 @@
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<mk-reactions-viewer :note="p"/>
|
<mk-reactions-viewer :note="p"/>
|
||||||
<button @click="reply" title="返信">
|
<button @click="reply" title="">
|
||||||
<template v-if="p.reply">%fa:reply-all%</template>
|
<template v-if="p.reply">%fa:reply-all%</template>
|
||||||
<template v-else>%fa:reply%</template>
|
<template v-else>%fa:reply%</template>
|
||||||
<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
|
<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button @click="renote" title="Renote">
|
<button @click="renote" title="%i18n:@renote%">
|
||||||
%fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
|
%fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="リアクション">
|
<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:@add-reaction%">
|
||||||
%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
|
%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button @click="menu" ref="menuButton">
|
<button @click="menu" ref="menuButton">
|
||||||
|
@ -104,8 +107,8 @@ export default Vue.extend({
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
context: [],
|
conversation: [],
|
||||||
contextFetching: false,
|
conversationFetching: false,
|
||||||
replies: []
|
replies: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -173,15 +176,15 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
fetchContext() {
|
fetchConversation() {
|
||||||
this.contextFetching = true;
|
this.conversationFetching = true;
|
||||||
|
|
||||||
// Fetch context
|
// Fetch conversation
|
||||||
(this as any).api('notes/context', {
|
(this as any).api('notes/conversation', {
|
||||||
noteId: this.p.replyId
|
noteId: this.p.replyId
|
||||||
}).then(context => {
|
}).then(conversation => {
|
||||||
this.contextFetching = false;
|
this.conversationFetching = false;
|
||||||
this.context = context.reverse();
|
this.conversation = conversation.reverse();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
reply() {
|
reply() {
|
||||||
|
@ -246,7 +249,7 @@ root(isDark)
|
||||||
&:disabled
|
&:disabled
|
||||||
color isDark ? #21242b : #ccc
|
color isDark ? #21242b : #ccc
|
||||||
|
|
||||||
> .context
|
> .conversation
|
||||||
> *
|
> *
|
||||||
border-bottom 1px solid isDark ? #1c2023 : #eef0f2
|
border-bottom 1px solid isDark ? #1c2023 : #eef0f2
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
|
||||||
|
<span class="is-admin" v-if="note.user.isAdmin">admin</span>
|
||||||
|
<span class="is-bot" v-if="note.user.isBot">bot</span>
|
||||||
|
<span class="is-cat" v-if="note.user.isCat">cat</span>
|
||||||
<span class="username"><mk-acct :user="note.user"/></span>
|
<span class="username"><mk-acct :user="note.user"/></span>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
||||||
|
@ -68,7 +71,6 @@ root(isDark)
|
||||||
align-items baseline
|
align-items baseline
|
||||||
margin-bottom 2px
|
margin-bottom 2px
|
||||||
white-space nowrap
|
white-space nowrap
|
||||||
line-height 21px
|
|
||||||
|
|
||||||
> .name
|
> .name
|
||||||
display block
|
display block
|
||||||
|
@ -84,6 +86,20 @@ root(isDark)
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration underline
|
text-decoration underline
|
||||||
|
|
||||||
|
> .is-admin
|
||||||
|
> .is-bot
|
||||||
|
> .is-cat
|
||||||
|
margin 0 0.5em 0 0
|
||||||
|
padding 1px 5px
|
||||||
|
font-size 10px
|
||||||
|
color isDark ? #758188 : #aaa
|
||||||
|
border solid 1px isDark ? #57616f : #ddd
|
||||||
|
border-radius 3px
|
||||||
|
|
||||||
|
&.is-admin
|
||||||
|
border-color isDark ? #d42c41 : #f56a7b
|
||||||
|
color isDark ? #d42c41 : #f56a7b
|
||||||
|
|
||||||
> .username
|
> .username
|
||||||
margin 0 .5em 0 0
|
margin 0 .5em 0 0
|
||||||
color isDark ? #606984 : #d1d8da
|
color isDark ? #606984 : #d1d8da
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
<div class="renote" v-if="isRenote">
|
<div class="renote" v-if="isRenote">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
%fa:retweet%
|
%fa:retweet%
|
||||||
<span>{{ '%i18n:!@reposted-by%'.substr(0, '%i18n:!@reposted-by%'.indexOf('{')) }}</span>
|
<span>{{ '%i18n:@reposted-by%'.substr(0, '%i18n:@reposted-by%'.indexOf('{')) }}</span>
|
||||||
<a class="name" :href="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</a>
|
<a class="name" :href="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</a>
|
||||||
<span>{{ '%i18n:!@reposted-by%'.substr('%i18n:!@reposted-by%'.indexOf('}') + 1) }}</span>
|
<span>{{ '%i18n:@reposted-by%'.substr('%i18n:@reposted-by%'.indexOf('}') + 1) }}</span>
|
||||||
<mk-time :time="note.createdAt"/>
|
<mk-time :time="note.createdAt"/>
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article>
|
||||||
|
@ -16,7 +16,9 @@
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
<router-link class="name" :to="p.user | userPage" v-user-preview="p.user.id">{{ p.user | userName }}</router-link>
|
<router-link class="name" :to="p.user | userPage" v-user-preview="p.user.id">{{ p.user | userName }}</router-link>
|
||||||
<span class="is-bot" v-if="p.user.host === null && p.user.isBot">bot</span>
|
<span class="is-admin" v-if="p.user.isAdmin">admin</span>
|
||||||
|
<span class="is-bot" v-if="p.user.isBot">bot</span>
|
||||||
|
<span class="is-cat" v-if="p.user.isCat">cat</span>
|
||||||
<span class="username"><mk-acct :user="p.user"/></span>
|
<span class="username"><mk-acct :user="p.user"/></span>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
|
<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
|
||||||
|
@ -430,7 +432,9 @@ root(isDark)
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration underline
|
text-decoration underline
|
||||||
|
|
||||||
|
> .is-admin
|
||||||
> .is-bot
|
> .is-bot
|
||||||
|
> .is-cat
|
||||||
margin 0 .5em 0 0
|
margin 0 .5em 0 0
|
||||||
padding 1px 6px
|
padding 1px 6px
|
||||||
font-size 12px
|
font-size 12px
|
||||||
|
@ -438,6 +442,10 @@ root(isDark)
|
||||||
border solid 1px isDark ? #57616f : #ddd
|
border solid 1px isDark ? #57616f : #ddd
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
|
|
||||||
|
&.is-admin
|
||||||
|
border-color isDark ? #d42c41 : #f56a7b
|
||||||
|
color isDark ? #d42c41 : #f56a7b
|
||||||
|
|
||||||
> .username
|
> .username
|
||||||
margin 0 .5em 0 0
|
margin 0 .5em 0 0
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
|
@ -145,9 +145,9 @@ export default Vue.extend({
|
||||||
this.notes.unshift(note);
|
this.notes.unshift(note);
|
||||||
|
|
||||||
// サウンドを再生する
|
// サウンドを再生する
|
||||||
if ((this as any).os.isEnableSounds && !silent) {
|
if (this.$store.state.device.enableSounds && !silent) {
|
||||||
const sound = new Audio(`${url}/assets/post.mp3`);
|
const sound = new Audio(`${url}/assets/post.mp3`);
|
||||||
sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 0.5;
|
sound.volume = this.$store.state.device.soundVolume;
|
||||||
sound.play();
|
sound.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
</transition-group>
|
</transition-group>
|
||||||
</div>
|
</div>
|
||||||
<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
|
<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
|
||||||
<template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>{{ fetchingMoreNotifications ? '%i18n:!common.loading%' : '%i18n:!@more%' }}
|
<template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
|
||||||
</button>
|
</button>
|
||||||
<p class="empty" v-if="notifications.length == 0 && !fetching">%i18n:@empty%</p>
|
<p class="empty" v-if="notifications.length == 0 && !fetching">%i18n:@empty%</p>
|
||||||
<p class="loading" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
|
<p class="loading" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
<span :class="$style.icon" v-if="geo">%fa:map-marker-alt%</span>
|
<span :class="$style.icon" v-if="geo">%fa:map-marker-alt%</span>
|
||||||
<span v-if="!reply">%i18n:@note%</span>
|
<span v-if="!reply">%i18n:@note%</span>
|
||||||
<span v-if="reply">%i18n:@reply%</span>
|
<span v-if="reply">%i18n:@reply%</span>
|
||||||
<span :class="$style.count" v-if="media.length != 0">{{ '%i18n:!@attaches%'.replace('{}', media.length) }}</span>
|
<span :class="$style.count" v-if="media.length != 0">{{ '%i18n:@attaches%'.replace('{}', media.length) }}</span>
|
||||||
<span :class="$style.count" v-if="uploadings.length != 0">{{ '%i18n:!@uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
|
<span :class="$style.count" v-if="uploadings.length != 0">{{ '%i18n:@uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<mk-note-preview v-if="reply" :class="$style.notePreview" :note="reply"/>
|
<mk-note-preview v-if="reply" :class="$style.notePreview" :note="reply"/>
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<button class="visibility" title="公開範囲" @click="setVisibility" ref="visibilityButton">%fa:lock%</button>
|
<button class="visibility" title="公開範囲" @click="setVisibility" ref="visibilityButton">%fa:lock%</button>
|
||||||
<p class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</p>
|
<p class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</p>
|
||||||
<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
|
<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
|
||||||
{{ posting ? '%i18n:!@posting%' : submitText }}<mk-ellipsis v-if="posting"/>
|
{{ posting ? '%i18n:@posting%' : submitText }}<mk-ellipsis v-if="posting"/>
|
||||||
</button>
|
</button>
|
||||||
<input ref="file" type="file" accept="image/*" multiple="multiple" tabindex="-1" @change="onChangeFile"/>
|
<input ref="file" type="file" accept="image/*" multiple="multiple" tabindex="-1" @change="onChangeFile"/>
|
||||||
<div class="dropzone" v-if="draghover"></div>
|
<div class="dropzone" v-if="draghover"></div>
|
||||||
|
@ -86,18 +86,18 @@ export default Vue.extend({
|
||||||
|
|
||||||
placeholder(): string {
|
placeholder(): string {
|
||||||
return this.renote
|
return this.renote
|
||||||
? '%i18n:!@quote-placeholder%'
|
? '%i18n:@quote-placeholder%'
|
||||||
: this.reply
|
: this.reply
|
||||||
? '%i18n:!@reply-placeholder%'
|
? '%i18n:@reply-placeholder%'
|
||||||
: '%i18n:!@note-placeholder%';
|
: '%i18n:@note-placeholder%';
|
||||||
},
|
},
|
||||||
|
|
||||||
submitText(): string {
|
submitText(): string {
|
||||||
return this.renote
|
return this.renote
|
||||||
? '%i18n:!@renote%'
|
? '%i18n:@renote%'
|
||||||
: this.reply
|
: this.reply
|
||||||
? '%i18n:!@reply%'
|
? '%i18n:@reply%'
|
||||||
: '%i18n:!@note%';
|
: '%i18n:@note%';
|
||||||
},
|
},
|
||||||
|
|
||||||
canPost(): boolean {
|
canPost(): boolean {
|
||||||
|
@ -304,16 +304,16 @@ export default Vue.extend({
|
||||||
this.deleteDraft();
|
this.deleteDraft();
|
||||||
this.$emit('posted');
|
this.$emit('posted');
|
||||||
(this as any).apis.notify(this.renote
|
(this as any).apis.notify(this.renote
|
||||||
? '%i18n:!@reposted%'
|
? '%i18n:@reposted%'
|
||||||
: this.reply
|
: this.reply
|
||||||
? '%i18n:!@replied%'
|
? '%i18n:@replied%'
|
||||||
: '%i18n:!@posted%');
|
: '%i18n:@posted%');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
(this as any).apis.notify(this.renote
|
(this as any).apis.notify(this.renote
|
||||||
? '%i18n:!@renote-failed%'
|
? '%i18n:@renote-failed%'
|
||||||
: this.reply
|
: this.reply
|
||||||
? '%i18n:!@reply-failed%'
|
? '%i18n:@reply-failed%'
|
||||||
: '%i18n:!@note-failed%');
|
: '%i18n:@note-failed%');
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.posting = false;
|
this.posting = false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<footer>
|
<footer>
|
||||||
<a class="quote" v-if="!quote" @click="onQuote">%i18n:@quote%</a>
|
<a class="quote" v-if="!quote" @click="onQuote">%i18n:@quote%</a>
|
||||||
<button class="ui cancel" @click="cancel">%i18n:@cancel%</button>
|
<button class="ui cancel" @click="cancel">%i18n:@cancel%</button>
|
||||||
<button class="ui primary ok" @click="ok" :disabled="wait">{{ wait ? '%i18n:!@reposting%' : '%i18n:!@renote%' }}</button>
|
<button class="ui primary ok" @click="ok" :disabled="wait">{{ wait ? '%i18n:@reposting%' : '%i18n:@renote%' }}</button>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="quote">
|
<template v-if="quote">
|
||||||
|
@ -32,9 +32,9 @@ export default Vue.extend({
|
||||||
renoteId: this.note.id
|
renoteId: this.note.id
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
this.$emit('posted');
|
this.$emit('posted');
|
||||||
(this as any).apis.notify('%i18n:!@success%');
|
(this as any).apis.notify('%i18n:@success%');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
(this as any).apis.notify('%i18n:!@failure%');
|
(this as any).apis.notify('%i18n:@failure%');
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.wait = false;
|
this.wait = false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<mk-window ref="window" is-modal width="700px" height="550px" @closed="$destroy">
|
<mk-window ref="window" is-modal width="700px" height="550px" @closed="$destroy">
|
||||||
<span slot="header" :class="$style.header">%fa:cog%設定</span>
|
<span slot="header" :class="$style.header">%fa:cog%%i18n:@settings%</span>
|
||||||
<mk-settings @done="close"/>
|
<mk-settings @done="close"/>
|
||||||
</mk-window>
|
</mk-window>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default Vue.extend({
|
||||||
methods: {
|
methods: {
|
||||||
register() {
|
register() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@enter-password%',
|
title: '%i18n:@enter-password%',
|
||||||
type: 'password'
|
type: 'password'
|
||||||
}).then(password => {
|
}).then(password => {
|
||||||
(this as any).api('i/2fa/register', {
|
(this as any).api('i/2fa/register', {
|
||||||
|
@ -47,13 +47,13 @@ export default Vue.extend({
|
||||||
|
|
||||||
unregister() {
|
unregister() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@enter-password%',
|
title: '%i18n:@enter-password%',
|
||||||
type: 'password'
|
type: 'password'
|
||||||
}).then(password => {
|
}).then(password => {
|
||||||
(this as any).api('i/2fa/unregister', {
|
(this as any).api('i/2fa/unregister', {
|
||||||
password: password
|
password: password
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
(this as any).apis.notify('%i18n:!@unregistered%');
|
(this as any).apis.notify('%i18n:@unregistered%');
|
||||||
(this as any).os.i.twoFactorEnabled = false;
|
(this as any).os.i.twoFactorEnabled = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -63,10 +63,10 @@ export default Vue.extend({
|
||||||
(this as any).api('i/2fa/done', {
|
(this as any).api('i/2fa/done', {
|
||||||
token: this.token
|
token: this.token
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
(this as any).apis.notify('%i18n:!@success%');
|
(this as any).apis.notify('%i18n:@success%');
|
||||||
(this as any).os.i.twoFactorEnabled = true;
|
(this as any).os.i.twoFactorEnabled = true;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
(this as any).apis.notify('%i18n:!@failed%');
|
(this as any).apis.notify('%i18n:@failed%');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default Vue.extend({
|
||||||
methods: {
|
methods: {
|
||||||
regenerateToken() {
|
regenerateToken() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@enter-password%',
|
title: '%i18n:@enter-password%',
|
||||||
type: 'password'
|
type: 'password'
|
||||||
}).then(password => {
|
}).then(password => {
|
||||||
(this as any).api('i/regenerate_token', {
|
(this as any).api('i/regenerate_token', {
|
||||||
|
|
|
@ -11,21 +11,21 @@ export default Vue.extend({
|
||||||
methods: {
|
methods: {
|
||||||
reset() {
|
reset() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@enter-current-password%',
|
title: '%i18n:@enter-current-password%',
|
||||||
type: 'password'
|
type: 'password'
|
||||||
}).then(currentPassword => {
|
}).then(currentPassword => {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@enter-new-password%',
|
title: '%i18n:@enter-new-password%',
|
||||||
type: 'password'
|
type: 'password'
|
||||||
}).then(newPassword => {
|
}).then(newPassword => {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: '%i18n:!@enter-new-password-again%',
|
title: '%i18n:@enter-new-password-again%',
|
||||||
type: 'password'
|
type: 'password'
|
||||||
}).then(newPassword2 => {
|
}).then(newPassword2 => {
|
||||||
if (newPassword !== newPassword2) {
|
if (newPassword !== newPassword2) {
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: null,
|
title: null,
|
||||||
text: '%i18n:!@not-match%',
|
text: '%i18n:@not-match%',
|
||||||
actions: [{
|
actions: [{
|
||||||
text: 'OK'
|
text: 'OK'
|
||||||
}]
|
}]
|
||||||
|
@ -36,7 +36,7 @@ export default Vue.extend({
|
||||||
currentPasword: currentPassword,
|
currentPasword: currentPassword,
|
||||||
newPassword: newPassword
|
newPassword: newPassword
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
(this as any).apis.notify('%i18n:!@changed%');
|
(this as any).apis.notify('%i18n:@changed%');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
<button class="ui primary" @click="save">%i18n:@save%</button>
|
<button class="ui primary" @click="save">%i18n:@save%</button>
|
||||||
<section>
|
<section>
|
||||||
<h2>その他</h2>
|
<h2>その他</h2>
|
||||||
<mk-switch v-model="os.i.isBot" @change="onChangeIsBot" text="このアカウントはbotです"/>
|
<mk-switch v-model="os.i.isBot" @change="onChangeIsBot" text="%i18n:@is-bot%"/>
|
||||||
|
<mk-switch v-model="os.i.isCat" @change="onChangeIsCat" text="%i18n:@is-cat%"/>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -65,6 +66,11 @@ export default Vue.extend({
|
||||||
(this as any).api('i/update', {
|
(this as any).api('i/update', {
|
||||||
isBot: (this as any).os.i.isBot
|
isBot: (this as any).os.i.isBot
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
onChangeIsCat() {
|
||||||
|
(this as any).api('i/update', {
|
||||||
|
isCat: (this as any).os.i.isCat
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -62,8 +62,10 @@
|
||||||
<el-slider
|
<el-slider
|
||||||
v-model="soundVolume"
|
v-model="soundVolume"
|
||||||
:show-input="true"
|
:show-input="true"
|
||||||
:format-tooltip="v => `${v}%`"
|
:format-tooltip="v => `${v * 100}%`"
|
||||||
:disabled="!enableSounds"
|
:disabled="!enableSounds"
|
||||||
|
:max="1"
|
||||||
|
:step="0.1"
|
||||||
/>
|
/>
|
||||||
<button class="ui button" @click="soundTest">%fa:volume-up% %i18n:@test%</button>
|
<button class="ui button" @click="soundTest">%fa:volume-up% %i18n:@test%</button>
|
||||||
</section>
|
</section>
|
||||||
|
@ -77,14 +79,10 @@
|
||||||
<h1>%i18n:@language%</h1>
|
<h1>%i18n:@language%</h1>
|
||||||
<el-select v-model="lang" placeholder="%i18n:@pick-language%">
|
<el-select v-model="lang" placeholder="%i18n:@pick-language%">
|
||||||
<el-option-group label="%i18n:@recommended%">
|
<el-option-group label="%i18n:@recommended%">
|
||||||
<el-option label="%i18n:@auto%" value=""/>
|
<el-option label="%i18n:@auto%" :value="null"/>
|
||||||
</el-option-group>
|
</el-option-group>
|
||||||
<el-option-group label="%i18n:@specify-language%">
|
<el-option-group label="%i18n:@specify-language%">
|
||||||
<el-option label="日本語" value="ja"/>
|
<el-option v-for="x in langs" :label="x[1]" :value="x[0]" :key="x[0]"/>
|
||||||
<el-option label="English" value="en"/>
|
|
||||||
<el-option label="Français" value="fr"/>
|
|
||||||
<el-option label="Polski" value="pl"/>
|
|
||||||
<el-option label="Deutsch" value="de"/>
|
|
||||||
</el-option-group>
|
</el-option-group>
|
||||||
</el-select>
|
</el-select>
|
||||||
<div class="none ui info">
|
<div class="none ui info">
|
||||||
|
@ -178,15 +176,7 @@
|
||||||
<mk-switch v-model="debug" text="%i18n:@debug-mode%">
|
<mk-switch v-model="debug" text="%i18n:@debug-mode%">
|
||||||
<span>%i18n:@debug-mode-desc%</span>
|
<span>%i18n:@debug-mode-desc%</span>
|
||||||
</mk-switch>
|
</mk-switch>
|
||||||
<template v-if="debug">
|
<mk-switch v-model="enableExperimentalFeatures" text="%i18n:@experimental%">
|
||||||
<mk-switch v-model="useRawScript" text="%i18n:@use-raw-script%">
|
|
||||||
<span>%i18n:@use-raw-script-desc%</span>
|
|
||||||
</mk-switch>
|
|
||||||
<div class="none ui info">
|
|
||||||
<p>%fa:info-circle%%i18n:@source-info%</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<mk-switch v-model="enableExperimental" text="%i18n:@experimental%">
|
|
||||||
<span>%i18n:@experimental-desc%</span>
|
<span>%i18n:@experimental-desc%</span>
|
||||||
</mk-switch>
|
</mk-switch>
|
||||||
<details v-if="debug">
|
<details v-if="debug">
|
||||||
|
@ -214,7 +204,7 @@ import XApi from './settings.api.vue';
|
||||||
import XApps from './settings.apps.vue';
|
import XApps from './settings.apps.vue';
|
||||||
import XSignins from './settings.signins.vue';
|
import XSignins from './settings.signins.vue';
|
||||||
import XDrive from './settings.drive.vue';
|
import XDrive from './settings.drive.vue';
|
||||||
import { url, docsUrl, license, lang, version } from '../../../config';
|
import { url, docsUrl, license, lang, langs, version } from '../../../config';
|
||||||
import checkForUpdate from '../../../common/scripts/check-for-update';
|
import checkForUpdate from '../../../common/scripts/check-for-update';
|
||||||
import MkTaskManager from './taskmanager.vue';
|
import MkTaskManager from './taskmanager.vue';
|
||||||
|
|
||||||
|
@ -235,55 +225,59 @@ export default Vue.extend({
|
||||||
meta: null,
|
meta: null,
|
||||||
license,
|
license,
|
||||||
version,
|
version,
|
||||||
|
langs,
|
||||||
latestVersion: undefined,
|
latestVersion: undefined,
|
||||||
checkingForUpdate: false,
|
checkingForUpdate: false
|
||||||
darkmode: localStorage.getItem('darkmode') == 'true',
|
|
||||||
enableSounds: localStorage.getItem('enableSounds') == 'true',
|
|
||||||
autoPopout: localStorage.getItem('autoPopout') == 'true',
|
|
||||||
apiViaStream: localStorage.getItem('apiViaStream') ? localStorage.getItem('apiViaStream') == 'true' : true,
|
|
||||||
soundVolume: localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) : 50,
|
|
||||||
lang: localStorage.getItem('lang') || '',
|
|
||||||
preventUpdate: localStorage.getItem('preventUpdate') == 'true',
|
|
||||||
debug: localStorage.getItem('debug') == 'true',
|
|
||||||
useRawScript: localStorage.getItem('useRawScript') == 'true',
|
|
||||||
enableExperimental: localStorage.getItem('enableExperimental') == 'true'
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
licenseUrl(): string {
|
licenseUrl(): string {
|
||||||
return `${docsUrl}/${lang}/license`;
|
return `${docsUrl}/${lang}/license`;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
autoPopout() {
|
apiViaStream: {
|
||||||
localStorage.setItem('autoPopout', this.autoPopout ? 'true' : 'false');
|
get() { return this.$store.state.device.apiViaStream; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'apiViaStream', value }); }
|
||||||
},
|
},
|
||||||
apiViaStream() {
|
|
||||||
localStorage.setItem('apiViaStream', this.apiViaStream ? 'true' : 'false');
|
autoPopout: {
|
||||||
|
get() { return this.$store.state.device.autoPopout; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'autoPopout', value }); }
|
||||||
},
|
},
|
||||||
darkmode() {
|
|
||||||
(this as any)._updateDarkmode_(this.darkmode);
|
darkmode: {
|
||||||
|
get() { return this.$store.state.device.darkmode; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'darkmode', value }); }
|
||||||
},
|
},
|
||||||
enableSounds() {
|
|
||||||
localStorage.setItem('enableSounds', this.enableSounds ? 'true' : 'false');
|
enableSounds: {
|
||||||
|
get() { return this.$store.state.device.enableSounds; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'enableSounds', value }); }
|
||||||
},
|
},
|
||||||
soundVolume() {
|
|
||||||
localStorage.setItem('soundVolume', this.soundVolume.toString());
|
soundVolume: {
|
||||||
|
get() { return this.$store.state.device.soundVolume; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'soundVolume', value }); }
|
||||||
},
|
},
|
||||||
lang() {
|
|
||||||
localStorage.setItem('lang', this.lang);
|
lang: {
|
||||||
|
get() { return this.$store.state.device.lang; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'lang', value }); }
|
||||||
},
|
},
|
||||||
preventUpdate() {
|
|
||||||
localStorage.setItem('preventUpdate', this.preventUpdate ? 'true' : 'false');
|
preventUpdate: {
|
||||||
|
get() { return this.$store.state.device.preventUpdate; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'preventUpdate', value }); }
|
||||||
},
|
},
|
||||||
debug() {
|
|
||||||
localStorage.setItem('debug', this.debug ? 'true' : 'false');
|
debug: {
|
||||||
|
get() { return this.$store.state.device.debug; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'debug', value }); }
|
||||||
},
|
},
|
||||||
useRawScript() {
|
|
||||||
localStorage.setItem('useRawScript', this.useRawScript ? 'true' : 'false');
|
enableExperimentalFeatures: {
|
||||||
},
|
get() { return this.$store.state.device.enableExperimentalFeatures; },
|
||||||
enableExperimental() {
|
set(value) { this.$store.commit('device/set', { key: 'enableExperimentalFeatures', value }); }
|
||||||
localStorage.setItem('enableExperimental', this.enableExperimental ? 'true' : 'false');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -371,13 +365,13 @@ export default Vue.extend({
|
||||||
this.latestVersion = newer;
|
this.latestVersion = newer;
|
||||||
if (newer == null) {
|
if (newer == null) {
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: '%i18n:!@no-updates%',
|
title: '%i18n:@no-updates%',
|
||||||
text: '%i18n:!@no-updates-desc%'
|
text: '%i18n:@no-updates-desc%'
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: '%i18n:!@update-available%',
|
title: '%i18n:@update-available%',
|
||||||
text: '%i18n:!@update-available-desc%'
|
text: '%i18n:@update-available-desc%'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -385,13 +379,13 @@ export default Vue.extend({
|
||||||
clean() {
|
clean() {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
(this as any).apis.dialog({
|
(this as any).apis.dialog({
|
||||||
title: '%i18n:!@cache-cleared%',
|
title: '%i18n:@cache-cleared%',
|
||||||
text: '%i18n:!@caache-cleared-desc%'
|
text: '%i18n:@caache-cleared-desc%'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
soundTest() {
|
soundTest() {
|
||||||
const sound = new Audio(`${url}/assets/message.mp3`);
|
const sound = new Audio(`${url}/assets/message.mp3`);
|
||||||
sound.volume = localStorage.getItem('soundVolume') ? parseInt(localStorage.getItem('soundVolume'), 10) / 100 : 0.5;
|
sound.volume = this.$store.state.device.soundVolume;
|
||||||
sound.play();
|
sound.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-sub-note-content">
|
<div class="mk-sub-note-content">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<span v-if="note.isHidden" style="opacity: 0.5">(この投稿は非公開です)</span>
|
<span v-if="note.isHidden" style="opacity: 0.5">%i18n:@hidden%</span>
|
||||||
<a class="reply" v-if="note.replyId">%fa:reply%</a>
|
<a class="reply" v-if="note.replyId">%fa:reply%</a>
|
||||||
<mk-note-html :text="note.text" :i="os.i"/>
|
<mk-note-html :text="note.text" :i="os.i"/>
|
||||||
<a class="rp" v-if="note.renoteId" :href="`/note:${note.renoteId}`">RP: ...</a>
|
<a class="rp" v-if="note.renoteId" :href="`/note:${note.renoteId}`">RP: ...</a>
|
||||||
</div>
|
</div>
|
||||||
<details v-if="note.media.length > 0">
|
<details v-if="note.media.length > 0">
|
||||||
<summary>({{ note.media.length }}つのメディア)</summary>
|
<summary>({{ note.media.length }}%i18n:@media%)</summary>
|
||||||
<mk-media-list :media-list="note.media"/>
|
<mk-media-list :media-list="note.media"/>
|
||||||
</details>
|
</details>
|
||||||
<details v-if="note.poll">
|
<details v-if="note.poll">
|
||||||
<summary>投票</summary>
|
<summary>%i18n:@poll%</summary>
|
||||||
<mk-poll :note="note"/>
|
<mk-poll :note="note"/>
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li @click="dark">
|
<li @click="dark">
|
||||||
<p><span>%i18n:@dark%</span><template v-if="_darkmode_">%fa:moon%</template><template v-else>%fa:R moon%</template></p>
|
<p><span>%i18n:@dark%</span><template v-if="$store.state.device.darkmode">%fa:moon%</template><template v-else>%fa:R moon%</template></p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -99,7 +99,10 @@ export default Vue.extend({
|
||||||
(this as any).os.signout();
|
(this as any).os.signout();
|
||||||
},
|
},
|
||||||
dark() {
|
dark() {
|
||||||
(this as any)._updateDarkmode_(!(this as any)._darkmode_);
|
this.$store.commit('device/set', {
|
||||||
|
key: 'darkmode',
|
||||||
|
value: !this.$store.state.device.darkmode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mk-window ref="window" is-modal width="450px" height="500px" @closed="$destroy">
|
<mk-window ref="window" is-modal width="450px" height="500px" @closed="$destroy">
|
||||||
<span slot="header">%fa:list% リスト</span>
|
<span slot="header">%fa:list% リスト</span>
|
||||||
|
|
||||||
<div data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82" :data-darkmode="_darkmode_">
|
<div data-id="6e4caea3-d8f9-4ab7-96de-ab67fe8d5c82" :data-darkmode="$store.state.device.darkmode">
|
||||||
<button class="ui" @click="add">%i18n:@create-list%</button>
|
<button class="ui" @click="add">%i18n:@create-list%</button>
|
||||||
<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
|
<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<span class="username">@{{ user | acct }}</span>
|
<span class="username">@{{ user | acct }}</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<p class="followed" v-if="user.isFollowed">フォローされています</p>
|
<p class="followed" v-if="user.isFollowed">%i18n:@followed%</p>
|
||||||
<div class="description">{{ user.description }}</div>
|
<div class="description">{{ user.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
>
|
>
|
||||||
<h1><slot name="header"></slot></h1>
|
<h1><slot name="header"></slot></h1>
|
||||||
<div>
|
<div>
|
||||||
<button class="popout" v-if="popoutUrl" @mousedown.stop="() => {}" @click="popout" title="ポップアウト">%fa:R window-restore%</button>
|
<button class="popout" v-if="popoutUrl" @mousedown.stop="() => {}" @click="popout" title="%i18n:@popout%">%fa:R window-restore%</button>
|
||||||
<button class="close" v-if="canClose" @mousedown.stop="() => {}" @click="close" title="閉じる">%fa:times%</button>
|
<button class="close" v-if="canClose" @mousedown.stop="() => {}" @click="close" title="%i18n:@close%">%fa:times%</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -95,7 +95,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
if (localStorage.getItem('autoPopout') == 'true' && this.popoutUrl) {
|
if ((this as any).os.store.state.device.autoPopout && this.popoutUrl) {
|
||||||
this.popout();
|
this.popout();
|
||||||
this.preventMount = true;
|
this.preventMount = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -16,11 +16,11 @@ export default Vue.extend({
|
||||||
this.folder = this.$route.params.folder;
|
this.folder = this.$route.params.folder;
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
document.title = 'Misskey Drive';
|
document.title = '%i18n:@title%';
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onMoveRoot() {
|
onMoveRoot() {
|
||||||
const title = 'Misskey Drive';
|
const title = '%i18n:@title%';
|
||||||
|
|
||||||
// Rewrite URL
|
// Rewrite URL
|
||||||
history.pushState(null, title, '/i/drive');
|
history.pushState(null, title, '/i/drive');
|
||||||
|
@ -28,7 +28,7 @@ export default Vue.extend({
|
||||||
document.title = title;
|
document.title = title;
|
||||||
},
|
},
|
||||||
onOpenFolder(folder) {
|
onOpenFolder(folder) {
|
||||||
const title = folder.name + ' | Misskey Drive';
|
const title = folder.name + ' | %i18n:@title%';
|
||||||
|
|
||||||
// Rewrite URL
|
// Rewrite URL
|
||||||
history.pushState(null, title, '/i/drive/folder/' + folder.id);
|
history.pushState(null, title, '/i/drive/folder/' + folder.id);
|
||||||
|
@ -49,4 +49,3 @@ export default Vue.extend({
|
||||||
> .mk-drive
|
> .mk-drive
|
||||||
height 100%
|
height 100%
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<template v-for="favorite in favorites">
|
<template v-for="favorite in favorites">
|
||||||
<mk-note-detail :note="favorite.note" :key="favorite.note.id"/>
|
<mk-note-detail :note="favorite.note" :key="favorite.note.id"/>
|
||||||
</template>
|
</template>
|
||||||
<a v-if="existMore" @click="more">さらに読み込む</a>
|
<a v-if="existMore" @click="more">%i18n:@more%</a>
|
||||||
</main>
|
</main>
|
||||||
</mk-ui>
|
</mk-ui>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
mounted() {
|
mounted() {
|
||||||
document.title = 'Misskey - ホームのカスタマイズ';
|
document.title = 'Misskey - %i18n:@title%';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -21,10 +21,21 @@ export default Vue.extend({
|
||||||
$route: 'fetch'
|
$route: 'fetch'
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
const applyBg = v =>
|
||||||
|
document.documentElement.style.setProperty('background', v ? '#191b22' : '#fff', 'important');
|
||||||
|
|
||||||
|
applyBg(this.$store.state.device.darkmode);
|
||||||
|
|
||||||
|
this.unwatchDarkmode = this.$store.watch(s => {
|
||||||
|
return s.device.darkmode;
|
||||||
|
}, applyBg);
|
||||||
|
|
||||||
this.fetch();
|
this.fetch();
|
||||||
},
|
},
|
||||||
mounted() {
|
beforeDestroy() {
|
||||||
document.documentElement.style.background = '#fff';
|
document.documentElement.style.removeProperty('background');
|
||||||
|
document.documentElement.style.removeProperty('background-color'); // for safari's bug
|
||||||
|
this.unwatchDarkmode();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetch() {
|
fetch() {
|
||||||
|
@ -50,6 +61,5 @@ export default Vue.extend({
|
||||||
flex 1
|
flex 1
|
||||||
flex-direction column
|
flex-direction column
|
||||||
min-height 100%
|
min-height 100%
|
||||||
background #fff
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -29,7 +29,7 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
document.title = '%i18n:!@title%';
|
document.title = '%i18n:@title%';
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSelected(file) {
|
onSelected(file) {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<mk-widget-container>
|
<mk-widget-container>
|
||||||
<template slot="header">%fa:users% ユーザー</template>
|
<template slot="header">%fa:users% %i18n:@users%</template>
|
||||||
<button slot="func" title="ユーザーを追加" @click="add">%fa:plus%</button>
|
<button slot="func" title="%i18n:@add-user%" @click="add">%fa:plus%</button>
|
||||||
|
|
||||||
<div data-id="d0b63759-a822-4556-a5ce-373ab966e08a">
|
<div data-id="d0b63759-a822-4556-a5ce-373ab966e08a">
|
||||||
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw% %i18n:common.loading%<mk-ellipsis/></p>
|
<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw% %i18n:common.loading%<mk-ellipsis/></p>
|
||||||
|
@ -48,7 +48,7 @@ export default Vue.extend({
|
||||||
methods: {
|
methods: {
|
||||||
add() {
|
add() {
|
||||||
(this as any).apis.input({
|
(this as any).apis.input({
|
||||||
title: 'ユーザー名',
|
title: '%i18n:@username%',
|
||||||
}).then(async username => {
|
}).then(async username => {
|
||||||
const user = await (this as any).api('users/show', {
|
const user = await (this as any).api('users/show', {
|
||||||
username
|
username
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="timeline">
|
<div class="timeline">
|
||||||
<header>
|
<header>
|
||||||
<span :data-active="mode == 'default'" @click="mode = 'default'">投稿</span>
|
<span :data-active="mode == 'default'" @click="mode = 'default'">%i18n:@default%</span>
|
||||||
<span :data-active="mode == 'with-replies'" @click="mode = 'with-replies'">投稿と返信</span>
|
<span :data-active="mode == 'with-replies'" @click="mode = 'with-replies'">%i18n:@with-replies%</span>
|
||||||
<span :data-active="mode == 'with-media'" @click="mode = 'with-media'">メディア</span>
|
<span :data-active="mode == 'with-media'" @click="mode = 'with-media'">%i18n:@with-media%</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="loading" v-if="fetching">
|
<div class="loading" v-if="fetching">
|
||||||
<mk-ellipsis-icon/>
|
<mk-ellipsis-icon/>
|
||||||
</div>
|
</div>
|
||||||
<mk-notes ref="timeline" :more="existMore ? more : null">
|
<mk-notes ref="timeline" :more="existMore ? more : null">
|
||||||
<p class="empty" slot="empty">%fa:R comments%このユーザーはまだ何も投稿していないようです。</p>
|
<p class="empty" slot="empty">%fa:R comments%%i18n:@empty%</p>
|
||||||
</mk-notes>
|
</mk-notes>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,24 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-welcome">
|
<div class="mk-welcome">
|
||||||
|
<button @click="dark">
|
||||||
|
<template v-if="$store.state.device.darkmode">%fa:moon%</template>
|
||||||
|
<template v-else>%fa:R moon%</template>
|
||||||
|
</button>
|
||||||
<main>
|
<main>
|
||||||
<div class="top">
|
<img :src="$store.state.device.darkmode ? 'assets/title-dark.svg' : 'assets/title.svg'" alt="Misskey">
|
||||||
<div>
|
<p><button class="signup" @click="signup">%i18n:@signup-button%</button><button class="signin" @click="signin">%i18n:@signin-button%</button></p>
|
||||||
<div>
|
|
||||||
<h1>Share<br><span ref="share">Everything!</span><span class="cursor">_</span></h1>
|
<div class="tl">
|
||||||
<p>ようこそ! <b>Misskey</b>はTwitter風ミニブログSNSです。思ったことや皆と共有したいことを投稿しましょう。タイムラインを見れば、皆の関心事をすぐにチェックすることもできます。<a :href="aboutUrl">詳しく...</a></p>
|
<header>%fa:comments R% %i18n:@timeline%<div><span></span><span></span><span></span></div></header>
|
||||||
<p><button class="signup" @click="signup">はじめる</button><button class="signin" @click="signin">ログイン</button></p>
|
|
||||||
<div class="users">
|
|
||||||
<mk-avatar class="avatar" v-for="user in users" :key="user.id" :user="user"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<header>%fa:comments R% タイムライン<div><span></span><span></span><span></span></div></header>
|
|
||||||
<mk-welcome-timeline/>
|
<mk-welcome-timeline/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
<mk-forkit/>
|
<mk-forkit/>
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -28,11 +21,11 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
<modal name="signup" width="500px" height="auto" scrollable>
|
<modal name="signup" width="500px" height="auto" scrollable>
|
||||||
<header :class="$style.signupFormHeader">新規登録</header>
|
<header :class="$style.signupFormHeader">%i18n:@signup%</header>
|
||||||
<mk-signup :class="$style.signupForm"/>
|
<mk-signup :class="$style.signupForm"/>
|
||||||
</modal>
|
</modal>
|
||||||
<modal name="signin" width="500px" height="auto" scrollable>
|
<modal name="signin" width="500px" height="auto" scrollable>
|
||||||
<header :class="$style.signinFormHeader">ログイン</header>
|
<header :class="$style.signinFormHeader">%i18n:@signin%</header>
|
||||||
<mk-signin :class="$style.signinForm"/>
|
<mk-signin :class="$style.signinForm"/>
|
||||||
</modal>
|
</modal>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,64 +35,25 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { docsUrl, copyright, lang } from '../../../config';
|
import { docsUrl, copyright, lang } from '../../../config';
|
||||||
|
|
||||||
const shares = [
|
|
||||||
'Everything!',
|
|
||||||
'Webpages',
|
|
||||||
'Photos',
|
|
||||||
'Interests',
|
|
||||||
'Favorites'
|
|
||||||
];
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
aboutUrl: `${docsUrl}/${lang}/about`,
|
aboutUrl: `${docsUrl}/${lang}/about`,
|
||||||
copyright,
|
copyright
|
||||||
users: [],
|
|
||||||
clock: null,
|
|
||||||
i: 0
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
(this as any).api('users', {
|
|
||||||
sort: '+follower',
|
|
||||||
limit: 20
|
|
||||||
}).then(users => {
|
|
||||||
this.users = users;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.clock = setInterval(() => {
|
|
||||||
if (++this.i == shares.length) this.i = 0;
|
|
||||||
const speed = 70;
|
|
||||||
const text = (this.$refs.share as any).innerText;
|
|
||||||
for (let i = 0; i < text.length; i++) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (this.$refs.share) {
|
|
||||||
(this.$refs.share as any).innerText = text.substr(0, text.length - i);
|
|
||||||
}
|
|
||||||
}, i * speed)
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
const newText = shares[this.i];
|
|
||||||
for (let i = 0; i <= newText.length; i++) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (this.$refs.share) {
|
|
||||||
(this.$refs.share as any).innerText = newText.substr(0, i);
|
|
||||||
}
|
|
||||||
}, i * speed)
|
|
||||||
}
|
|
||||||
}, text.length * speed);
|
|
||||||
}, 4000);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.clock);
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
signup() {
|
signup() {
|
||||||
this.$modal.show('signup');
|
this.$modal.show('signup');
|
||||||
},
|
},
|
||||||
signin() {
|
signin() {
|
||||||
this.$modal.show('signin');
|
this.$modal.show('signin');
|
||||||
|
},
|
||||||
|
dark() {
|
||||||
|
this.$store.commit('device/set', {
|
||||||
|
key: 'darkmode',
|
||||||
|
value: !this.$store.state.device.darkmode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -115,73 +69,31 @@ export default Vue.extend({
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@import '~const.styl'
|
@import '~const.styl'
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css?family=Sarpanch:700')
|
root(isDark)
|
||||||
|
|
||||||
.mk-welcome
|
|
||||||
display flex
|
display flex
|
||||||
flex-direction column
|
flex-direction column
|
||||||
flex 1
|
flex 1
|
||||||
$width = 1000px
|
|
||||||
|
|
||||||
background linear-gradient(to bottom, #1e1d65, #bd6659)
|
> button
|
||||||
//background-image url('/assets/welcome-bg.svg')
|
position absolute
|
||||||
background-size cover
|
z-index 1
|
||||||
background-position top center
|
top 0
|
||||||
|
|
||||||
&:before
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
position fixed
|
|
||||||
bottom 0
|
|
||||||
left 0
|
left 0
|
||||||
width 100%
|
padding 16px
|
||||||
height 100%
|
font-size 18px
|
||||||
background-image url('/assets/welcome-fg.svg')
|
color isDark ? #fff : #555
|
||||||
background-size cover
|
|
||||||
background-position bottom center
|
|
||||||
|
|
||||||
> main
|
> main
|
||||||
display flex
|
|
||||||
flex 1
|
flex 1
|
||||||
|
padding 64px 0 0 0
|
||||||
|
text-align center
|
||||||
|
color isDark ? #9aa4b3 : #555
|
||||||
|
|
||||||
> .top
|
> img
|
||||||
display flex
|
width 350px
|
||||||
width 100%
|
|
||||||
|
|
||||||
> div
|
|
||||||
display flex
|
|
||||||
max-width $width + 64px
|
|
||||||
margin 0 auto
|
|
||||||
padding 80px 32px 0 32px
|
|
||||||
|
|
||||||
> *
|
|
||||||
margin-bottom 48px
|
|
||||||
|
|
||||||
> div:first-child
|
|
||||||
margin-right 48px
|
|
||||||
color #fff
|
|
||||||
text-shadow 0 0 12px #172062
|
|
||||||
|
|
||||||
> h1
|
|
||||||
margin 0
|
|
||||||
font-weight bold
|
|
||||||
//font-variant small-caps
|
|
||||||
letter-spacing 12px
|
|
||||||
font-family 'Sarpanch', sans-serif
|
|
||||||
font-size 42px
|
|
||||||
line-height 48px
|
|
||||||
|
|
||||||
> .cursor
|
|
||||||
animation cursor 1s infinite linear both
|
|
||||||
|
|
||||||
@keyframes cursor
|
|
||||||
0%
|
|
||||||
opacity 1
|
|
||||||
50%
|
|
||||||
opacity 0
|
|
||||||
|
|
||||||
> p
|
> p
|
||||||
margin 1em 0
|
margin 8px 0
|
||||||
line-height 2em
|
line-height 2em
|
||||||
|
|
||||||
button
|
button
|
||||||
|
@ -207,31 +119,21 @@ export default Vue.extend({
|
||||||
|
|
||||||
.signin
|
.signin
|
||||||
&:hover
|
&:hover
|
||||||
color #fff
|
color isDark ? #fff : #000
|
||||||
|
|
||||||
> .users
|
> .tl
|
||||||
margin 16px 0 0 0
|
margin 32px auto 0 auto
|
||||||
|
|
||||||
> *
|
|
||||||
display inline-block
|
|
||||||
margin 4px
|
|
||||||
width 38px
|
|
||||||
height 38px
|
|
||||||
border-radius 6px
|
|
||||||
|
|
||||||
> div:last-child
|
|
||||||
|
|
||||||
> div
|
|
||||||
width 410px
|
width 410px
|
||||||
background #fff
|
text-align left
|
||||||
|
background isDark ? #313543 : #fff
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
box-shadow 0 0 0 12px rgba(#000, 0.1)
|
box-shadow 0 8px 32px rgba(#000, 0.15)
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
> header
|
> header
|
||||||
z-index 1
|
z-index 1
|
||||||
padding 12px 16px
|
padding 12px 16px
|
||||||
color #888d94
|
color isDark ? #e3e5e8 : #888d94
|
||||||
box-shadow 0 1px 0px rgba(#000, 0.1)
|
box-shadow 0 1px 0px rgba(#000, 0.1)
|
||||||
|
|
||||||
> div
|
> div
|
||||||
|
@ -245,7 +147,6 @@ export default Vue.extend({
|
||||||
height 11px
|
height 11px
|
||||||
width 11px
|
width 11px
|
||||||
margin-left 6px
|
margin-left 6px
|
||||||
background #ccc
|
|
||||||
border-radius 100%
|
border-radius 100%
|
||||||
vertical-align middle
|
vertical-align middle
|
||||||
|
|
||||||
|
@ -264,12 +165,11 @@ export default Vue.extend({
|
||||||
|
|
||||||
> footer
|
> footer
|
||||||
font-size 12px
|
font-size 12px
|
||||||
color #949ea5
|
color isDark ? #949ea5 : #737c82
|
||||||
|
|
||||||
> div
|
> div
|
||||||
max-width $width
|
|
||||||
margin 0 auto
|
margin 0 auto
|
||||||
padding 0 0 42px 0
|
padding 64px
|
||||||
text-align center
|
text-align center
|
||||||
|
|
||||||
> .c
|
> .c
|
||||||
|
@ -277,6 +177,12 @@ export default Vue.extend({
|
||||||
font-size 10px
|
font-size 10px
|
||||||
opacity 0.7
|
opacity 0.7
|
||||||
|
|
||||||
|
.mk-welcome[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.mk-welcome:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="stylus" module>
|
<style lang="stylus" module>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<template slot="header">%fa:chart-pie%%i18n:@title%</template>
|
<template slot="header">%fa:chart-pie%%i18n:@title%</template>
|
||||||
<button slot="func" title="%i18n:@refresh%" @click="fetch">%fa:sync%</button>
|
<button slot="func" title="%i18n:@refresh%" @click="fetch">%fa:sync%</button>
|
||||||
|
|
||||||
<div class="mkw-polls--body" :data-darkmode="_darkmode_">
|
<div class="mkw-polls--body" :data-darkmode="$store.state.device.darkmode">
|
||||||
<div class="poll" v-if="!fetching && poll != null">
|
<div class="poll" v-if="!fetching && poll != null">
|
||||||
<p v-if="poll.text"><router-link to="poll | notePage">{{ poll.text }}</router-link></p>
|
<p v-if="poll.text"><router-link to="poll | notePage">{{ poll.text }}</router-link></p>
|
||||||
<p v-if="!poll.text"><router-link to="poll | notePage">%fa:link%</router-link></p>
|
<p v-if="!poll.text"><router-link to="poll | notePage">%fa:link%</router-link></p>
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
>
|
>
|
||||||
<div class="banner"
|
<div class="banner"
|
||||||
:style="os.i.bannerUrl ? `background-image: url(${os.i.bannerUrl}?thumbnail&size=256)` : ''"
|
:style="os.i.bannerUrl ? `background-image: url(${os.i.bannerUrl}?thumbnail&size=256)` : ''"
|
||||||
title="クリックでバナー編集"
|
title="%i18n:@update-banner%"
|
||||||
@click="os.apis.updateBanner"
|
@click="os.apis.updateBanner"
|
||||||
></div>
|
></div>
|
||||||
<mk-avatar class="avatar" :user="os.i"
|
<mk-avatar class="avatar" :user="os.i"
|
||||||
@click="os.apis.updateAvatar"
|
@click="os.apis.updateAvatar"
|
||||||
title="クリックでアバター編集"
|
title="%i18n:@update-avatar%"
|
||||||
/>
|
/>
|
||||||
<router-link class="name" :to="os.i | userPage">{{ os.i | userName }}</router-link>
|
<router-link class="name" :to="os.i | userPage">{{ os.i | userName }}</router-link>
|
||||||
<p class="username">@{{ os.i | acct }}</p>
|
<p class="username">@{{ os.i | acct }}</p>
|
||||||
|
|
|
@ -49,48 +49,6 @@ Vue.mixin({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Dark/Light
|
|
||||||
const bus = new Vue();
|
|
||||||
Vue.mixin({
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
_darkmode_: localStorage.getItem('darkmode') == 'true'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
beforeCreate() {
|
|
||||||
// なぜか警告が出るので
|
|
||||||
this._darkmode_ = localStorage.getItem('darkmode') == 'true';
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
bus.$off('updated', this._onDarkmodeUpdated_);
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this._onDarkmodeUpdated_(this._darkmode_);
|
|
||||||
bus.$on('updated', this._onDarkmodeUpdated_);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
_updateDarkmode_(v) {
|
|
||||||
localStorage.setItem('darkmode', v.toString());
|
|
||||||
if (v) {
|
|
||||||
document.documentElement.setAttribute('data-darkmode', 'true');
|
|
||||||
} else {
|
|
||||||
document.documentElement.removeAttribute('data-darkmode');
|
|
||||||
}
|
|
||||||
bus.$emit('updated', v);
|
|
||||||
},
|
|
||||||
_onDarkmodeUpdated_(v) {
|
|
||||||
if (!this.$el || !this.$el.setAttribute) return;
|
|
||||||
if (v) {
|
|
||||||
this.$el.setAttribute('data-darkmode', 'true');
|
|
||||||
} else {
|
|
||||||
this.$el.removeAttribute('data-darkmode');
|
|
||||||
}
|
|
||||||
this._darkmode_ = v;
|
|
||||||
this.$forceUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APP ENTRY POINT!
|
* APP ENTRY POINT!
|
||||||
*/
|
*/
|
||||||
|
@ -113,7 +71,7 @@ html.setAttribute('lang', lang);
|
||||||
const head = document.getElementsByTagName('head')[0];
|
const head = document.getElementsByTagName('head')[0];
|
||||||
const meta = document.createElement('meta');
|
const meta = document.createElement('meta');
|
||||||
meta.setAttribute('name', 'description');
|
meta.setAttribute('name', 'description');
|
||||||
meta.setAttribute('content', '%i18n:!common.misskey%');
|
meta.setAttribute('content', '%i18n:common.misskey%');
|
||||||
head.appendChild(meta);
|
head.appendChild(meta);
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
@ -141,13 +99,52 @@ export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API)
|
||||||
const launch = (router: VueRouter, api?: (os: MiOS) => API) => {
|
const launch = (router: VueRouter, api?: (os: MiOS) => API) => {
|
||||||
os.apis = api ? api(os) : null;
|
os.apis = api ? api(os) : null;
|
||||||
|
|
||||||
|
//#region Dark/Light
|
||||||
|
Vue.mixin({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
_unwatchDarkmode_: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const apply = v => {
|
||||||
|
if (this.$el.setAttribute == null) return;
|
||||||
|
if (v) {
|
||||||
|
this.$el.setAttribute('data-darkmode', 'true');
|
||||||
|
} else {
|
||||||
|
this.$el.removeAttribute('data-darkmode');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
apply(os.store.state.device.darkmode);
|
||||||
|
|
||||||
|
this._unwatchDarkmode_ = os.store.watch(s => {
|
||||||
|
return s.device.darkmode;
|
||||||
|
}, apply);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this._unwatchDarkmode_();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
os.store.watch(s => {
|
||||||
|
return s.device.darkmode;
|
||||||
|
}, v => {
|
||||||
|
if (v) {
|
||||||
|
document.documentElement.setAttribute('data-darkmode', 'true');
|
||||||
|
} else {
|
||||||
|
document.documentElement.removeAttribute('data-darkmode');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//#endregion
|
||||||
|
|
||||||
Vue.mixin({
|
Vue.mixin({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
os,
|
os,
|
||||||
api: os.api,
|
api: os.api,
|
||||||
apis: os.apis,
|
apis: os.apis,
|
||||||
clientSettings: os.store.state.settings.data
|
clientSettings: os.store.state.settings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -173,7 +170,7 @@ export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API)
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region 更新チェック
|
//#region 更新チェック
|
||||||
const preventUpdate = localStorage.getItem('preventUpdate') == 'true';
|
const preventUpdate = os.store.state.device.preventUpdate;
|
||||||
if (!preventUpdate) {
|
if (!preventUpdate) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
checkForUpdate(os);
|
checkForUpdate(os);
|
||||||
|
|
|
@ -98,14 +98,7 @@ export default class MiOS extends EventEmitter {
|
||||||
* Whether is debug mode
|
* Whether is debug mode
|
||||||
*/
|
*/
|
||||||
public get debug() {
|
public get debug() {
|
||||||
return localStorage.getItem('debug') == 'true';
|
return this.store ? this.store.state.device.debug : false;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether enable sounds
|
|
||||||
*/
|
|
||||||
public get isEnableSounds() {
|
|
||||||
return localStorage.getItem('enableSounds') == 'true';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public store: ReturnType<typeof initStore>;
|
public store: ReturnType<typeof initStore>;
|
||||||
|
@ -435,12 +428,8 @@ export default class MiOS extends EventEmitter {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Whether use raw version script
|
|
||||||
const raw = (localStorage.getItem('useRawScript') == 'true' && this.debug)
|
|
||||||
|| process.env.NODE_ENV != 'production';
|
|
||||||
|
|
||||||
// The path of service worker script
|
// The path of service worker script
|
||||||
const sw = `/sw.${version}.${lang}.${raw ? 'raw' : 'min'}.js`;
|
const sw = `/sw.${version}.${lang}.js`;
|
||||||
|
|
||||||
// Register service worker
|
// Register service worker
|
||||||
navigator.serviceWorker.register(sw).then(registration => {
|
navigator.serviceWorker.register(sw).then(registration => {
|
||||||
|
@ -471,8 +460,7 @@ export default class MiOS extends EventEmitter {
|
||||||
};
|
};
|
||||||
|
|
||||||
const promise = new Promise((resolve, reject) => {
|
const promise = new Promise((resolve, reject) => {
|
||||||
const viaStream = this.stream && this.stream.hasConnection &&
|
const viaStream = this.stream && this.stream.hasConnection && this.store.state.device.apiViaStream;
|
||||||
(localStorage.getItem('apiViaStream') ? localStorage.getItem('apiViaStream') == 'true' : true);
|
|
||||||
|
|
||||||
if (viaStream) {
|
if (viaStream) {
|
||||||
const stream = this.stream.borrow();
|
const stream = this.stream.borrow();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import VueRouter from 'vue-router';
|
import VueRouter from 'vue-router';
|
||||||
|
|
||||||
import { MdCard, MdButton, MdField, MdMenu, MdList, MdSwitch } from 'vue-material/dist/components';
|
import { MdCard, MdButton, MdField, MdMenu, MdList, MdSwitch, MdSubheader, MdDialog, MdDialogAlert, MdRadio } from 'vue-material/dist/components';
|
||||||
import 'vue-material/dist/vue-material.min.css';
|
import 'vue-material/dist/vue-material.min.css';
|
||||||
import 'vue-material/dist/theme/default.css';
|
import 'vue-material/dist/theme/default.css';
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ import MkSearch from './views/pages/search.vue';
|
||||||
import MkFollowers from './views/pages/followers.vue';
|
import MkFollowers from './views/pages/followers.vue';
|
||||||
import MkFollowing from './views/pages/following.vue';
|
import MkFollowing from './views/pages/following.vue';
|
||||||
import MkSettings from './views/pages/settings.vue';
|
import MkSettings from './views/pages/settings.vue';
|
||||||
import MkProfileSetting from './views/pages/profile-setting.vue';
|
|
||||||
import MkOthello from './views/pages/othello.vue';
|
import MkOthello from './views/pages/othello.vue';
|
||||||
|
|
||||||
Vue.use(MdCard);
|
Vue.use(MdCard);
|
||||||
|
@ -46,6 +45,10 @@ Vue.use(MdField);
|
||||||
Vue.use(MdMenu);
|
Vue.use(MdMenu);
|
||||||
Vue.use(MdList);
|
Vue.use(MdList);
|
||||||
Vue.use(MdSwitch);
|
Vue.use(MdSwitch);
|
||||||
|
Vue.use(MdSubheader);
|
||||||
|
Vue.use(MdDialog);
|
||||||
|
Vue.use(MdDialogAlert);
|
||||||
|
Vue.use(MdRadio);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init
|
* init
|
||||||
|
@ -67,8 +70,7 @@ init((launch) => {
|
||||||
routes: [
|
routes: [
|
||||||
{ path: '/', name: 'index', component: MkIndex },
|
{ path: '/', name: 'index', component: MkIndex },
|
||||||
{ path: '/signup', name: 'signup', component: MkSignup },
|
{ path: '/signup', name: 'signup', component: MkSignup },
|
||||||
{ path: '/i/settings', component: MkSettings },
|
{ path: '/i/settings', name: 'settings', component: MkSettings },
|
||||||
{ path: '/i/settings/profile', component: MkProfileSetting },
|
|
||||||
{ path: '/i/notifications', name: 'notifications', component: MkNotifications },
|
{ path: '/i/notifications', name: 'notifications', component: MkNotifications },
|
||||||
{ path: '/i/widgets', name: 'widgets', component: MkWidgets },
|
{ path: '/i/widgets', name: 'widgets', component: MkWidgets },
|
||||||
{ path: '/i/messaging', name: 'messaging', component: MkMessaging },
|
{ path: '/i/messaging', name: 'messaging', component: MkMessaging },
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<div class="files" v-if="files.length > 0">
|
<div class="files" v-if="files.length > 0">
|
||||||
<x-file v-for="file in files" :key="file.id" :file="file"/>
|
<x-file v-for="file in files" :key="file.id" :file="file"/>
|
||||||
<button class="more" v-if="moreFiles" @click="fetchMoreFiles">
|
<button class="more" v-if="moreFiles" @click="fetchMoreFiles">
|
||||||
{{ fetchingMoreFiles ? '%i18n:!common.loading%' : '%i18n:!@load-more%' }}
|
{{ fetchingMoreFiles ? '%i18n:common.loading%' : '%i18n:@load-more%' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
|
<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<template v-if="!wait && user.isFollowing">%fa:minus%</template>
|
<template v-if="!wait && user.isFollowing">%fa:minus%</template>
|
||||||
<template v-if="!wait && !user.isFollowing">%fa:plus%</template>
|
<template v-if="!wait && !user.isFollowing">%fa:plus%</template>
|
||||||
<template v-if="wait">%fa:spinner .pulse .fw%</template>
|
<template v-if="wait">%fa:spinner .pulse .fw%</template>
|
||||||
{{ user.isFollowing ? '%i18n:!@unfollow%' : '%i18n:!@follow%' }}
|
{{ user.isFollowing ? '%i18n:@unfollow%' : '%i18n:@follow%' }}
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,17 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
style(): any {
|
style(): any {
|
||||||
|
let url = `url(${this.image.url}?thumbnail)`;
|
||||||
|
|
||||||
|
if (this.$store.state.device.loadRemoteMedia || this.$store.state.device.lightmode) {
|
||||||
|
url = null;
|
||||||
|
} else if (this.raw || this.$store.state.device.loadRawImages) {
|
||||||
|
url = `url(${this.image.url})`;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'background-color': this.image.properties.avgColor && this.image.properties.avgColor.length == 3 ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent',
|
'background-color': this.image.properties.avgColor && this.image.properties.avgColor.length == 3 ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent',
|
||||||
'background-image': this.raw ? `url(${this.image.url})` : `url(${this.image.url}?thumbnail&size=512)`
|
'background-image': url
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
<div class="mk-note-detail">
|
<div class="mk-note-detail">
|
||||||
<button
|
<button
|
||||||
class="more"
|
class="more"
|
||||||
v-if="p.reply && p.reply.replyId && context.length == 0"
|
v-if="p.reply && p.reply.replyId && conversation.length == 0"
|
||||||
@click="fetchContext"
|
@click="fetchConversation"
|
||||||
:disabled="fetchingContext"
|
:disabled="conversationFetching"
|
||||||
>
|
>
|
||||||
<template v-if="!contextFetching">%fa:ellipsis-v%</template>
|
<template v-if="!conversationFetching">%fa:ellipsis-v%</template>
|
||||||
<template v-if="contextFetching">%fa:spinner .pulse%</template>
|
<template v-if="conversationFetching">%fa:spinner .pulse%</template>
|
||||||
</button>
|
</button>
|
||||||
<div class="context">
|
<div class="conversation">
|
||||||
<x-sub v-for="note in context" :key="note.id" :note="note"/>
|
<x-sub v-for="note in conversation" :key="note.id" :note="note"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="reply-to" v-if="p.reply">
|
<div class="reply-to" v-if="p.reply">
|
||||||
<x-sub :note="p.reply"/>
|
<x-sub :note="p.reply"/>
|
||||||
|
@ -99,8 +99,8 @@ export default Vue.extend({
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
context: [],
|
conversation: [],
|
||||||
contextFetching: false,
|
conversationFetching: false,
|
||||||
replies: []
|
replies: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -166,14 +166,14 @@ export default Vue.extend({
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
fetchContext() {
|
fetchContext() {
|
||||||
this.contextFetching = true;
|
this.conversationFetching = true;
|
||||||
|
|
||||||
// Fetch context
|
// Fetch conversation
|
||||||
(this as any).api('notes/context', {
|
(this as any).api('notes/conversation', {
|
||||||
noteId: this.p.replyId
|
noteId: this.p.replyId
|
||||||
}).then(context => {
|
}).then(conversation => {
|
||||||
this.contextFetching = false;
|
this.conversationFetching = false;
|
||||||
this.context = context.reverse();
|
this.conversation = conversation.reverse();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
reply() {
|
reply() {
|
||||||
|
@ -245,7 +245,7 @@ root(isDark)
|
||||||
&:disabled
|
&:disabled
|
||||||
color #ccc
|
color #ccc
|
||||||
|
|
||||||
> .context
|
> .conversation
|
||||||
> *
|
> *
|
||||||
border-bottom 1px solid isDark ? #1c2023 : #eef0f2
|
border-bottom 1px solid isDark ? #1c2023 : #eef0f2
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-note-preview">
|
<div class="mk-note-preview" :class="{ smart: $store.state.device.postStyle == 'smart' }">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle != 'smart'"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
|
<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle == 'smart'"/>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
|
<span class="is-admin" v-if="note.user.isAdmin">admin</span>
|
||||||
|
<span class="is-bot" v-if="note.user.isBot">bot</span>
|
||||||
|
<span class="is-cat" v-if="note.user.isCat">cat</span>
|
||||||
<span class="username"><mk-acct :user="note.user"/></span>
|
<span class="username"><mk-acct :user="note.user"/></span>
|
||||||
<router-link class="time" :to="note | notePage">
|
<router-link class="time" :to="note | notePage">
|
||||||
<mk-time :time="note.createdAt"/>
|
<mk-time :time="note.createdAt"/>
|
||||||
|
@ -35,6 +39,13 @@ root(isDark)
|
||||||
display block
|
display block
|
||||||
clear both
|
clear both
|
||||||
|
|
||||||
|
&.smart
|
||||||
|
> .main
|
||||||
|
width 100%
|
||||||
|
|
||||||
|
> header
|
||||||
|
align-items center
|
||||||
|
|
||||||
> .avatar
|
> .avatar
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
|
@ -53,6 +64,13 @@ root(isDark)
|
||||||
margin-bottom 4px
|
margin-bottom 4px
|
||||||
white-space nowrap
|
white-space nowrap
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
flex-shrink 0
|
||||||
|
margin-right 8px
|
||||||
|
width 18px
|
||||||
|
height 18px
|
||||||
|
border-radius 100%
|
||||||
|
|
||||||
> .name
|
> .name
|
||||||
display block
|
display block
|
||||||
margin 0 .5em 0 0
|
margin 0 .5em 0 0
|
||||||
|
@ -65,8 +83,19 @@ root(isDark)
|
||||||
text-decoration none
|
text-decoration none
|
||||||
text-overflow ellipsis
|
text-overflow ellipsis
|
||||||
|
|
||||||
&:hover
|
> .is-admin
|
||||||
text-decoration underline
|
> .is-bot
|
||||||
|
> .is-cat
|
||||||
|
margin 0 0.5em 0 0
|
||||||
|
padding 1px 6px
|
||||||
|
font-size 10px
|
||||||
|
color isDark ? #758188 : #aaa
|
||||||
|
border solid 1px isDark ? #57616f : #ddd
|
||||||
|
border-radius 3px
|
||||||
|
|
||||||
|
&.is-admin
|
||||||
|
border-color isDark ? #d42c41 : #f56a7b
|
||||||
|
color isDark ? #d42c41 : #f56a7b
|
||||||
|
|
||||||
> .username
|
> .username
|
||||||
margin 0 .5em 0 0
|
margin 0 .5em 0 0
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="sub">
|
<div class="sub" :class="{ smart: $store.state.device.postStyle == 'smart' }">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle != 'smart'"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
|
<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle == 'smart'"/>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
|
<span class="is-admin" v-if="note.user.isAdmin">admin</span>
|
||||||
|
<span class="is-bot" v-if="note.user.isBot">bot</span>
|
||||||
|
<span class="is-cat" v-if="note.user.isCat">cat</span>
|
||||||
<span class="username"><mk-acct :user="note.user"/></span>
|
<span class="username"><mk-acct :user="note.user"/></span>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
|
||||||
|
@ -42,6 +46,13 @@ root(isDark)
|
||||||
@media (min-width 600px)
|
@media (min-width 600px)
|
||||||
padding 24px 32px
|
padding 24px 32px
|
||||||
|
|
||||||
|
&.smart
|
||||||
|
> .main
|
||||||
|
width 100%
|
||||||
|
|
||||||
|
> header
|
||||||
|
align-items center
|
||||||
|
|
||||||
&:after
|
&:after
|
||||||
content ""
|
content ""
|
||||||
display block
|
display block
|
||||||
|
@ -73,6 +84,13 @@ root(isDark)
|
||||||
margin-bottom 2px
|
margin-bottom 2px
|
||||||
white-space nowrap
|
white-space nowrap
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
flex-shrink 0
|
||||||
|
margin-right 8px
|
||||||
|
width 18px
|
||||||
|
height 18px
|
||||||
|
border-radius 100%
|
||||||
|
|
||||||
> .name
|
> .name
|
||||||
display block
|
display block
|
||||||
margin 0 0.5em 0 0
|
margin 0 0.5em 0 0
|
||||||
|
@ -88,6 +106,20 @@ root(isDark)
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration underline
|
text-decoration underline
|
||||||
|
|
||||||
|
> .is-admin
|
||||||
|
> .is-bot
|
||||||
|
> .is-cat
|
||||||
|
margin 0 0.5em 0 0
|
||||||
|
padding 1px 5px
|
||||||
|
font-size 10px
|
||||||
|
color isDark ? #758188 : #aaa
|
||||||
|
border solid 1px isDark ? #57616f : #ddd
|
||||||
|
border-radius 3px
|
||||||
|
|
||||||
|
&.is-admin
|
||||||
|
border-color isDark ? #d42c41 : #f56a7b
|
||||||
|
color isDark ? #d42c41 : #f56a7b
|
||||||
|
|
||||||
> .username
|
> .username
|
||||||
text-align left
|
text-align left
|
||||||
margin 0
|
margin 0
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="note" :class="{ renote: isRenote }">
|
<div class="note" :class="{ renote: isRenote, smart: $store.state.device.postStyle == 'smart' }">
|
||||||
<div class="reply-to" v-if="p.reply && (!os.isSignedIn || clientSettings.showReplyTarget)">
|
<div class="reply-to" v-if="p.reply && (!os.isSignedIn || clientSettings.showReplyTarget)">
|
||||||
<x-sub :note="p.reply"/>
|
<x-sub :note="p.reply"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="renote" v-if="isRenote">
|
<div class="renote" v-if="isRenote">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
%fa:retweet%
|
%fa:retweet%
|
||||||
<span>{{ '%i18n:!@reposted-by%'.substr(0, '%i18n:!@reposted-by%'.indexOf('{')) }}</span>
|
<span>{{ '%i18n:@reposted-by%'.substr(0, '%i18n:@reposted-by%'.indexOf('{')) }}</span>
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
||||||
<span>{{ '%i18n:!@reposted-by%'.substr('%i18n:!@reposted-by%'.indexOf('}') + 1) }}</span>
|
<span>{{ '%i18n:@reposted-by%'.substr('%i18n:@reposted-by%'.indexOf('}') + 1) }}</span>
|
||||||
<mk-time :time="note.createdAt"/>
|
<mk-time :time="note.createdAt"/>
|
||||||
</div>
|
</div>
|
||||||
<article>
|
<article>
|
||||||
<mk-avatar class="avatar" :user="p.user"/>
|
<mk-avatar class="avatar" :user="p.user" v-if="$store.state.device.postStyle != 'smart'"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<header>
|
<header>
|
||||||
|
<mk-avatar class="avatar" :user="p.user" v-if="$store.state.device.postStyle == 'smart'"/>
|
||||||
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
|
<router-link class="name" :to="p.user | userPage">{{ p.user | userName }}</router-link>
|
||||||
<span class="is-bot" v-if="p.user.host === null && p.user.isBot">bot</span>
|
<span class="is-admin" v-if="p.user.isAdmin">admin</span>
|
||||||
|
<span class="is-bot" v-if="p.user.isBot">bot</span>
|
||||||
|
<span class="is-cat" v-if="p.user.isCat">cat</span>
|
||||||
<span class="username"><mk-acct :user="p.user"/></span>
|
<span class="username"><mk-acct :user="p.user"/></span>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
|
<span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
|
||||||
|
@ -262,6 +265,15 @@ root(isDark)
|
||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
font-size 16px
|
font-size 16px
|
||||||
|
|
||||||
|
&.smart
|
||||||
|
> article
|
||||||
|
> .main
|
||||||
|
width 100%
|
||||||
|
|
||||||
|
> header
|
||||||
|
align-items center
|
||||||
|
margin-bottom 4px
|
||||||
|
|
||||||
> .renote
|
> .renote
|
||||||
display flex
|
display flex
|
||||||
align-items center
|
align-items center
|
||||||
|
@ -278,12 +290,17 @@ root(isDark)
|
||||||
padding 16px 32px
|
padding 16px 32px
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
|
flex-shrink 0
|
||||||
display inline-block
|
display inline-block
|
||||||
width 28px
|
width 20px
|
||||||
height 28px
|
height 20px
|
||||||
margin 0 8px 0 0
|
margin 0 8px 0 0
|
||||||
border-radius 6px
|
border-radius 6px
|
||||||
|
|
||||||
|
@media (min-width 500px)
|
||||||
|
width 28px
|
||||||
|
height 28px
|
||||||
|
|
||||||
[data-fa]
|
[data-fa]
|
||||||
margin-right 4px
|
margin-right 4px
|
||||||
|
|
||||||
|
@ -352,21 +369,26 @@ root(isDark)
|
||||||
@media (min-width 500px)
|
@media (min-width 500px)
|
||||||
margin-bottom 2px
|
margin-bottom 2px
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
flex-shrink 0
|
||||||
|
margin-right 8px
|
||||||
|
width 20px
|
||||||
|
height 20px
|
||||||
|
border-radius 100%
|
||||||
|
|
||||||
> .name
|
> .name
|
||||||
display block
|
display block
|
||||||
margin 0 0.5em 0 0
|
margin 0 0.5em 0 0
|
||||||
padding 0
|
padding 0
|
||||||
overflow hidden
|
overflow hidden
|
||||||
color isDark ? #fff : #627079
|
color isDark ? #fff : #627079
|
||||||
font-size 1em
|
|
||||||
font-weight bold
|
font-weight bold
|
||||||
text-decoration none
|
text-decoration none
|
||||||
text-overflow ellipsis
|
text-overflow ellipsis
|
||||||
|
|
||||||
&:hover
|
> .is-admin
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
> .is-bot
|
> .is-bot
|
||||||
|
> .is-cat
|
||||||
margin 0 0.5em 0 0
|
margin 0 0.5em 0 0
|
||||||
padding 1px 6px
|
padding 1px 6px
|
||||||
font-size 12px
|
font-size 12px
|
||||||
|
@ -374,6 +396,10 @@ root(isDark)
|
||||||
border solid 1px isDark ? #57616f : #ddd
|
border solid 1px isDark ? #57616f : #ddd
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
|
|
||||||
|
&.is-admin
|
||||||
|
border-color isDark ? #d42c41 : #f56a7b
|
||||||
|
color isDark ? #d42c41 : #f56a7b
|
||||||
|
|
||||||
> .username
|
> .username
|
||||||
margin 0 0.5em 0 0
|
margin 0 0.5em 0 0
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<button class="more" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
|
<button class="more" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
|
||||||
<template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>
|
<template v-if="fetchingMoreNotifications">%fa:spinner .pulse .fw%</template>
|
||||||
{{ fetchingMoreNotifications ? '%i18n:!common.loading%' : '%i18n:!@more%' }}
|
{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<p class="empty" v-if="notifications.length == 0 && !fetching">%i18n:@empty%</p>
|
<p class="empty" v-if="notifications.length == 0 && !fetching">%i18n:@empty%</p>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<a @click="addVisibleUser">+ユーザーを追加</a>
|
<a @click="addVisibleUser">+ユーザーを追加</a>
|
||||||
</div>
|
</div>
|
||||||
<input v-show="useCw" v-model="cw" placeholder="内容への注釈 (オプション)">
|
<input v-show="useCw" v-model="cw" placeholder="内容への注釈 (オプション)">
|
||||||
<textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:!@reply-placeholder%' : renote ? '%i18n:!@renote-placeholder%' : '%i18n:!@note-placeholder%'"></textarea>
|
<textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:@reply-placeholder%' : renote ? '%i18n:@renote-placeholder%' : '%i18n:@note-placeholder%'"></textarea>
|
||||||
<div class="attaches" v-show="files.length != 0">
|
<div class="attaches" v-show="files.length != 0">
|
||||||
<x-draggable class="files" :list="files" :options="{ animation: 150 }">
|
<x-draggable class="files" :list="files" :options="{ animation: 150 }">
|
||||||
<div class="file" v-for="file in files" :key="file.id">
|
<div class="file" v-for="file in files" :key="file.id">
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
<li><a @click="search">%fa:search%%i18n:@search%%fa:angle-right%</a></li>
|
<li><a @click="search">%fa:search%%i18n:@search%%fa:angle-right%</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li><router-link to="/i/settings">%fa:cog%%i18n:@settings%%fa:angle-right%</router-link></li>
|
<li><router-link to="/i/settings" :data-active="$route.name == 'settings'">%fa:cog%%i18n:@settings%%fa:angle-right%</router-link></li>
|
||||||
<li @click="dark"><p><template v-if="_darkmode_">%fa:moon%</template><template v-else>%fa:R moon%</template><span>ダークモード</span></p></li>
|
<li @click="dark"><p><template v-if="$store.state.device.darkmode">%fa:moon%</template><template v-else>%fa:R moon%</template><span>ダークモード</span></p></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<a :href="aboutUrl"><p class="about">%i18n:@about%</p></a>
|
<a :href="aboutUrl"><p class="about">%i18n:@about%</p></a>
|
||||||
|
@ -94,7 +94,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
search() {
|
search() {
|
||||||
const query = window.prompt('%i18n:!@search%');
|
const query = window.prompt('%i18n:@search%');
|
||||||
if (query == null || query == '') return;
|
if (query == null || query == '') return;
|
||||||
this.$router.push('/search?q=' + encodeURIComponent(query));
|
this.$router.push('/search?q=' + encodeURIComponent(query));
|
||||||
},
|
},
|
||||||
|
@ -117,7 +117,10 @@ export default Vue.extend({
|
||||||
this.hasGameInvitations = false;
|
this.hasGameInvitations = false;
|
||||||
},
|
},
|
||||||
dark() {
|
dark() {
|
||||||
(this as any)._updateDarkmode_(!(this as any)._darkmode_);
|
this.$store.commit('device/set', {
|
||||||
|
key: 'darkmode',
|
||||||
|
value: !this.$store.state.device.darkmode
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-user-card">
|
<div class="mk-user-card">
|
||||||
<header :style="user.bannerUrl ? `background-image: url(${user.bannerUrl}?thumbnail&size=1024)` : ''">
|
<header :style="user.bannerUrl ? `background-image: url(${user.bannerUrl}?thumbnail&size=1024)` : ''">
|
||||||
<a :href="user | userPage">
|
<mk-avatar class="avatar" :user="user"/>
|
||||||
<img :src="`${user.avatarUrl}?thumbnail&size=200`" alt="avatar"/>
|
|
||||||
</a>
|
|
||||||
</header>
|
</header>
|
||||||
<a class="name" :href="user | userPage" target="_blank">{{ user | userName }}</a>
|
<a class="name" :href="user | userPage" target="_blank">{{ user | userName }}</a>
|
||||||
<p class="username"><mk-acct :user="user"/></p>
|
<p class="username"><mk-acct :user="user"/></p>
|
||||||
|
@ -35,8 +33,7 @@ export default Vue.extend({
|
||||||
background-position center
|
background-position center
|
||||||
border-radius 8px 8px 0 0
|
border-radius 8px 8px 0 0
|
||||||
|
|
||||||
> a
|
> .avatar
|
||||||
> img
|
|
||||||
position absolute
|
position absolute
|
||||||
top 20px
|
top 20px
|
||||||
left calc(50% - 40px)
|
left calc(50% - 40px)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<mk-notes ref="timeline" :more="existMore ? more : null">
|
<mk-notes ref="timeline" :more="existMore ? more : null">
|
||||||
<div slot="empty">
|
<div slot="empty">
|
||||||
%fa:R comments%
|
%fa:R comments%
|
||||||
{{ withMedia ? '%i18n:!@no-notes-with-media%' : '%i18n:!@no-notes%' }}
|
{{ withMedia ? '%i18n:@no-notes-with-media%' : '%i18n:@no-notes%' }}
|
||||||
</div>
|
</div>
|
||||||
</mk-notes>
|
</mk-notes>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mk-ui>
|
<mk-ui>
|
||||||
<template slot="header" v-if="!fetching">
|
<template slot="header" v-if="!fetching">
|
||||||
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt="">
|
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt="">
|
||||||
{{ '%i18n:!@followers-of%'.replace('{}', name) }}
|
{{ '%i18n:@followers-of%'.replace('{}', name) }}
|
||||||
</template>
|
</template>
|
||||||
<mk-users-list
|
<mk-users-list
|
||||||
v-if="!fetching"
|
v-if="!fetching"
|
||||||
|
@ -49,7 +49,7 @@ export default Vue.extend({
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
|
|
||||||
document.title = '%i18n:!@followers-of%'.replace('{}', this.name) + ' | Misskey';
|
document.title = '%i18n:@followers-of%'.replace('{}', this.name) + ' | Misskey';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLoaded() {
|
onLoaded() {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mk-ui>
|
<mk-ui>
|
||||||
<template slot="header" v-if="!fetching">
|
<template slot="header" v-if="!fetching">
|
||||||
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt="">
|
<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt="">
|
||||||
{{ '%i18n:!@following-of%'.replace('{}', name) }}
|
{{ '%i18n:@following-of%'.replace('{}', name) }}
|
||||||
</template>
|
</template>
|
||||||
<mk-users-list
|
<mk-users-list
|
||||||
v-if="!fetching"
|
v-if="!fetching"
|
||||||
|
@ -48,7 +48,7 @@ export default Vue.extend({
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
|
|
||||||
document.title = '%i18n:!@followers-of%'.replace('{}', this.name) + ' | Misskey';
|
document.title = '%i18n:@followers-of%'.replace('{}', this.name) + ' | Misskey';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLoaded() {
|
onLoaded() {
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
<mk-ui>
|
<mk-ui>
|
||||||
<span slot="header" @click="showNav = true">
|
<span slot="header" @click="showNav = true">
|
||||||
<span>
|
<span>
|
||||||
<span v-if="src == 'home'">%fa:home%ホーム</span>
|
<span v-if="src == 'home'">%fa:home%%i18n:@home%</span>
|
||||||
<span v-if="src == 'local'">%fa:R comments%ローカル</span>
|
<span v-if="src == 'local'">%fa:R comments%%i18n:@local%</span>
|
||||||
<span v-if="src == 'global'">%fa:globe%グローバル</span>
|
<span v-if="src == 'global'">%fa:globe%%i18n:@global%</span>
|
||||||
<span v-if="src.startsWith('list')">%fa:list%{{ list.title }}</span>
|
<span v-if="src.startsWith('list')">%fa:list%{{ list.title }}</span>
|
||||||
</span>
|
</span>
|
||||||
<span style="margin-left:8px">
|
<span style="margin-left:8px">
|
||||||
|
@ -17,14 +17,14 @@
|
||||||
<button @click="fn">%fa:pencil-alt%</button>
|
<button @click="fn">%fa:pencil-alt%</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<main :data-darkmode="_darkmode_">
|
<main :data-darkmode="$store.state.device.darkmode">
|
||||||
<div class="nav" v-if="showNav">
|
<div class="nav" v-if="showNav">
|
||||||
<div class="bg" @click="showNav = false"></div>
|
<div class="bg" @click="showNav = false"></div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div>
|
<div>
|
||||||
<span :data-active="src == 'home'" @click="src = 'home'">%fa:home% ホーム</span>
|
<span :data-active="src == 'home'" @click="src = 'home'">%fa:home% %i18n:@home%</span>
|
||||||
<span :data-active="src == 'local'" @click="src = 'local'">%fa:R comments% ローカル</span>
|
<span :data-active="src == 'local'" @click="src = 'local'">%fa:R comments% %i18n:@local%</span>
|
||||||
<span :data-active="src == 'global'" @click="src = 'global'">%fa:globe% グローバル</span>
|
<span :data-active="src == 'global'" @click="src = 'global'">%fa:globe% %i18n:@global%</span>
|
||||||
<template v-if="lists">
|
<template v-if="lists">
|
||||||
<span v-for="l in lists" :data-active="src == 'list:' + l.id" @click="src = 'list:' + l.id; list = l" :key="l.id">%fa:list% {{ l.title }}</span>
|
<span v-for="l in lists" :data-active="src == 'list:' + l.id" @click="src = 'list:' + l.id; list = l" :key="l.id">%fa:list% {{ l.title }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -16,16 +16,30 @@ export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fetching: true,
|
fetching: true,
|
||||||
user: null
|
user: null,
|
||||||
|
unwatchDarkmode: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: 'fetch'
|
$route: 'fetch'
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
document.documentElement.style.background = '#fff';
|
const applyBg = v =>
|
||||||
|
document.documentElement.style.setProperty('background', v ? '#191b22' : '#fff', 'important');
|
||||||
|
|
||||||
|
applyBg(this.$store.state.device.darkmode);
|
||||||
|
|
||||||
|
this.unwatchDarkmode = this.$store.watch(s => {
|
||||||
|
return s.device.darkmode;
|
||||||
|
}, applyBg);
|
||||||
|
|
||||||
this.fetch();
|
this.fetch();
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
document.documentElement.style.removeProperty('background');
|
||||||
|
document.documentElement.style.removeProperty('background-color'); // for safari's bug
|
||||||
|
this.unwatchDarkmode();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetch() {
|
fetch() {
|
||||||
this.fetching = true;
|
this.fetching = true;
|
||||||
|
@ -39,4 +53,3 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import getAcct from '../../../../../acct/render';
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
mounted() {
|
mounted() {
|
||||||
document.title = 'Misskey %i18n:@messaging%';
|
document.title = 'Misskey %i18n:@messaging%';
|
||||||
document.documentElement.style.background = '#fff';
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
navigate(user) {
|
navigate(user) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fn() {
|
fn() {
|
||||||
const ok = window.confirm('%i18n:!@read-all%');
|
const ok = window.confirm('%i18n:@read-all%');
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|
||||||
(this as any).api('notifications/markAsRead_all');
|
(this as any).api('notifications/markAsRead_all');
|
||||||
|
|
|
@ -1,225 +0,0 @@
|
||||||
<template>
|
|
||||||
<mk-ui>
|
|
||||||
<span slot="header">%fa:user%%i18n:@title%</span>
|
|
||||||
<div :class="$style.content">
|
|
||||||
<p>%fa:info-circle%%i18n:@will-be-published%</p>
|
|
||||||
<div :class="$style.form">
|
|
||||||
<div :style="os.i.bannerUrl ? `background-image: url(${os.i.bannerUrl}?thumbnail&size=1024)` : ''" @click="setBanner">
|
|
||||||
<img :src="`${os.i.avatarUrl}?thumbnail&size=200`" alt="avatar" @click="setAvatar"/>
|
|
||||||
</div>
|
|
||||||
<label>
|
|
||||||
<p>%i18n:@name%</p>
|
|
||||||
<input v-model="name" type="text"/>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p>%i18n:@location%</p>
|
|
||||||
<input v-model="location" type="text"/>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p>%i18n:@description%</p>
|
|
||||||
<textarea v-model="description"></textarea>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p>%i18n:@birthday%</p>
|
|
||||||
<input v-model="birthday" type="date"/>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p>%i18n:@avatar%</p>
|
|
||||||
<button @click="setAvatar" :disabled="avatarSaving">%i18n:@set-avatar%</button>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p>%i18n:@banner%</p>
|
|
||||||
<button @click="setBanner" :disabled="bannerSaving">%i18n:@set-banner%</button>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<button :class="$style.save" @click="save" :disabled="saving">%fa:check%%i18n:@save%</button>
|
|
||||||
</div>
|
|
||||||
</mk-ui>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
export default Vue.extend({
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
name: null,
|
|
||||||
location: null,
|
|
||||||
description: null,
|
|
||||||
birthday: null,
|
|
||||||
avatarSaving: false,
|
|
||||||
bannerSaving: false,
|
|
||||||
saving: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.name = (this as any).os.i.name || '';
|
|
||||||
this.location = (this as any).os.i.profile.location;
|
|
||||||
this.description = (this as any).os.i.description;
|
|
||||||
this.birthday = (this as any).os.i.profile.birthday;
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
document.title = 'Misskey | %i18n:@title%';
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
setAvatar() {
|
|
||||||
(this as any).apis.chooseDriveFile({
|
|
||||||
multiple: false
|
|
||||||
}).then(file => {
|
|
||||||
this.avatarSaving = true;
|
|
||||||
|
|
||||||
(this as any).api('i/update', {
|
|
||||||
avatarId: file.id
|
|
||||||
}).then(() => {
|
|
||||||
this.avatarSaving = false;
|
|
||||||
alert('%i18n:!@avatar-saved%');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setBanner() {
|
|
||||||
(this as any).apis.chooseDriveFile({
|
|
||||||
multiple: false
|
|
||||||
}).then(file => {
|
|
||||||
this.bannerSaving = true;
|
|
||||||
|
|
||||||
(this as any).api('i/update', {
|
|
||||||
bannerId: file.id
|
|
||||||
}).then(() => {
|
|
||||||
this.bannerSaving = false;
|
|
||||||
alert('%i18n:!@banner-saved%');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.saving = true;
|
|
||||||
|
|
||||||
(this as any).api('i/update', {
|
|
||||||
name: this.name || null,
|
|
||||||
location: this.location || null,
|
|
||||||
description: this.description || null,
|
|
||||||
birthday: this.birthday || null
|
|
||||||
}).then(() => {
|
|
||||||
this.saving = false;
|
|
||||||
alert('%i18n:!@saved%');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" module>
|
|
||||||
@import '~const.styl'
|
|
||||||
|
|
||||||
.content
|
|
||||||
margin 8px auto
|
|
||||||
max-width 500px
|
|
||||||
width calc(100% - 16px)
|
|
||||||
|
|
||||||
@media (min-width 500px)
|
|
||||||
margin 16px auto
|
|
||||||
width calc(100% - 32px)
|
|
||||||
|
|
||||||
> p
|
|
||||||
display block
|
|
||||||
margin 0 0 8px 0
|
|
||||||
padding 12px 16px
|
|
||||||
font-size 14px
|
|
||||||
color #79d4e6
|
|
||||||
border solid 1px #71afbb
|
|
||||||
//color #276f86
|
|
||||||
//background #f8ffff
|
|
||||||
//border solid 1px #a9d5de
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> [data-fa]
|
|
||||||
margin-right 6px
|
|
||||||
|
|
||||||
.form
|
|
||||||
position relative
|
|
||||||
background #fff
|
|
||||||
box-shadow 0 0 0 1px rgba(#000, 0.2)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&:before
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom -20px
|
|
||||||
left calc(50% - 10px)
|
|
||||||
border-top solid 10px rgba(#000, 0.2)
|
|
||||||
border-right solid 10px transparent
|
|
||||||
border-bottom solid 10px transparent
|
|
||||||
border-left solid 10px transparent
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
bottom -16px
|
|
||||||
left calc(50% - 8px)
|
|
||||||
border-top solid 8px #fff
|
|
||||||
border-right solid 8px transparent
|
|
||||||
border-bottom solid 8px transparent
|
|
||||||
border-left solid 8px transparent
|
|
||||||
|
|
||||||
> div
|
|
||||||
height 128px
|
|
||||||
background-color #e4e4e4
|
|
||||||
background-size cover
|
|
||||||
background-position center
|
|
||||||
border-radius 8px 8px 0 0
|
|
||||||
|
|
||||||
> img
|
|
||||||
position absolute
|
|
||||||
top 25px
|
|
||||||
left calc(50% - 40px)
|
|
||||||
width 80px
|
|
||||||
height 80px
|
|
||||||
border solid 2px #fff
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> label
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
border-bottom solid 1px #eee
|
|
||||||
|
|
||||||
&:last-of-type
|
|
||||||
border none
|
|
||||||
|
|
||||||
> p:first-child
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0 0 4px 0
|
|
||||||
font-weight bold
|
|
||||||
color #2f3c42
|
|
||||||
|
|
||||||
> input[type="text"]
|
|
||||||
> textarea
|
|
||||||
display block
|
|
||||||
width 100%
|
|
||||||
padding 12px
|
|
||||||
font-size 16px
|
|
||||||
color #192427
|
|
||||||
border solid 2px #ddd
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> textarea
|
|
||||||
min-height 80px
|
|
||||||
|
|
||||||
.save
|
|
||||||
display block
|
|
||||||
margin 8px 0 0 0
|
|
||||||
padding 16px
|
|
||||||
width 100%
|
|
||||||
font-size 16px
|
|
||||||
color $theme-color-foreground
|
|
||||||
background $theme-color
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
&:disabled
|
|
||||||
opacity 0.7
|
|
||||||
|
|
||||||
> [data-fa]
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -3,7 +3,7 @@
|
||||||
<span slot="header">%fa:search% {{ q }}</span>
|
<span slot="header">%fa:search% {{ q }}</span>
|
||||||
<main v-if="!fetching">
|
<main v-if="!fetching">
|
||||||
<mk-notes :class="$style.notes" :notes="notes">
|
<mk-notes :class="$style.notes" :notes="notes">
|
||||||
<span v-if="notes.length == 0">{{ '%i18n:!@empty%'.replace('{}', q) }}</span>
|
<span v-if="notes.length == 0">{{ '%i18n:@empty%'.replace('{}', q) }}</span>
|
||||||
<button v-if="existMore" @click="more" :disabled="fetching" slot="tail">
|
<button v-if="existMore" @click="more" :disabled="fetching" slot="tail">
|
||||||
<span v-if="!fetching">%i18n:@load-more%</span>
|
<span v-if="!fetching">%i18n:@load-more%</span>
|
||||||
<span v-if="fetching">%i18n:common.loading%<mk-ellipsis/></span>
|
<span v-if="fetching">%i18n:common.loading%<mk-ellipsis/></span>
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
document.title = '%i18n:!@title%';
|
document.title = '%i18n:@title%';
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onSelected(file) {
|
onSelected(file) {
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<mk-ui>
|
<mk-ui>
|
||||||
<span slot="header">%fa:cog%%i18n:@settings%</span>
|
<span slot="header">%fa:cog%%i18n:@settings%</span>
|
||||||
<main>
|
<main>
|
||||||
<p v-html="'%i18n:!@signed-in-as%'.replace('{}', '<b>' + name + '</b>')"></p>
|
<p v-html="'%i18n:@signed-in-as%'.replace('{}', '<b>' + name + '</b>')"></p>
|
||||||
<div>
|
<div>
|
||||||
<x-profile/>
|
<x-profile/>
|
||||||
|
|
||||||
<md-card class="md-layout-item md-size-50 md-small-size-100">
|
<md-card>
|
||||||
<md-card-header>
|
<md-card-header>
|
||||||
<div class="md-title">%i18n:@design%</div>
|
<div class="md-title">%fa:palette% %i18n:@design%</div>
|
||||||
</md-card-header>
|
</md-card-header>
|
||||||
|
|
||||||
<md-card-content>
|
<md-card-content>
|
||||||
|
@ -19,6 +19,110 @@
|
||||||
<div>
|
<div>
|
||||||
<md-switch v-model="clientSettings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</md-switch>
|
<md-switch v-model="clientSettings.circleIcons" @change="onChangeCircleIcons">%i18n:@circle-icons%</md-switch>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="md-body-2">%i18n:@timeline%</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="clientSettings.showReplyTarget" @change="onChangeShowReplyTarget">%i18n:@show-reply-target%</md-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="clientSettings.showMyRenotes" @change="onChangeShowMyRenotes">%i18n:@show-my-renotes%</md-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="clientSettings.showRenotedMyNotes" @change="onChangeShowRenotedMyNotes">%i18n:@show-renoted-my-notes%</md-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="md-body-2">%i18n:@post-style%</div>
|
||||||
|
|
||||||
|
<md-radio v-model="postStyle" value="standard">%i18n:@post-style-standard%</md-radio>
|
||||||
|
<md-radio v-model="postStyle" value="smart">%i18n:@post-style-smart%</md-radio>
|
||||||
|
</div>
|
||||||
|
</md-card-content>
|
||||||
|
</md-card>
|
||||||
|
|
||||||
|
<md-card>
|
||||||
|
<md-card-header>
|
||||||
|
<div class="md-title">%fa:cog% %i18n:@behavior%</div>
|
||||||
|
</md-card-header>
|
||||||
|
|
||||||
|
<md-card-content>
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="clientSettings.fetchOnScroll" @change="onChangeFetchOnScroll">%i18n:@fetch-on-scroll%</md-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="clientSettings.disableViaMobile" @change="onChangeDisableViaMobile">%i18n:@disable-via-mobile%</md-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="loadRawImages">%i18n:@load-raw-images%</md-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="clientSettings.loadRemoteMedia" @change="onChangeLoadRemoteMedia">%i18n:@load-remote-media%</md-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<md-switch v-model="lightmode">%i18n:@i-am-under-limited-internet%</md-switch>
|
||||||
|
</div>
|
||||||
|
</md-card-content>
|
||||||
|
</md-card>
|
||||||
|
|
||||||
|
<md-card>
|
||||||
|
<md-card-header>
|
||||||
|
<div class="md-title">%fa:language% %i18n:@lang%</div>
|
||||||
|
</md-card-header>
|
||||||
|
|
||||||
|
<md-card-content>
|
||||||
|
<md-field>
|
||||||
|
<md-select v-model="lang" placeholder="%i18n:@auto%">
|
||||||
|
<md-optgroup label="%i18n:@recommended%">
|
||||||
|
<md-option value="">%i18n:@auto%</md-option>
|
||||||
|
</md-optgroup>
|
||||||
|
|
||||||
|
<md-optgroup label="%i18n:@specify-language%">
|
||||||
|
<md-option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</md-option>
|
||||||
|
</md-optgroup>
|
||||||
|
</md-select>
|
||||||
|
</md-field>
|
||||||
|
<span class="md-helper-text">%fa:info-circle% %i18n:@lang-tip%</span>
|
||||||
|
</md-card-content>
|
||||||
|
</md-card>
|
||||||
|
|
||||||
|
<md-card>
|
||||||
|
<md-card-header>
|
||||||
|
<div class="md-title">%fa:B twitter% %i18n:@twitter%</div>
|
||||||
|
</md-card-header>
|
||||||
|
|
||||||
|
<md-card-content>
|
||||||
|
<p class="account" v-if="os.i.twitter"><a :href="`https://twitter.com/${os.i.twitter.screenName}`" target="_blank">@{{ os.i.twitter.screenName }}</a></p>
|
||||||
|
<p>
|
||||||
|
<a :href="`${apiUrl}/connect/twitter`" target="_blank">{{ os.i.twitter ? '%i18n:@twitter-reconnect%' : '%i18n:@twitter-connect%' }}</a>
|
||||||
|
<span v-if="os.i.twitter"> or </span>
|
||||||
|
<a :href="`${apiUrl}/disconnect/twitter`" target="_blank" v-if="os.i.twitter">%i18n:@twitter-disconnect%</a>
|
||||||
|
</p>
|
||||||
|
</md-card-content>
|
||||||
|
</md-card>
|
||||||
|
|
||||||
|
<md-card>
|
||||||
|
<md-card-header>
|
||||||
|
<div class="md-title">%fa:sync-alt% %i18n:@update%</div>
|
||||||
|
</md-card-header>
|
||||||
|
|
||||||
|
<md-card-content>
|
||||||
|
<div>%i18n:@version% <i>{{ version }}</i></div>
|
||||||
|
<template v-if="latestVersion !== undefined">
|
||||||
|
<div>%i18n:@latest-version% <i>{{ latestVersion ? latestVersion : version }}</i></div>
|
||||||
|
</template>
|
||||||
|
<md-button class="md-raised md-primary" @click="checkForUpdate" :disabled="checkingForUpdate">
|
||||||
|
<template v-if="checkingForUpdate">%i18n:@update-checking%<mk-ellipsis/></template>
|
||||||
|
<template v-else>%i18n:@check-for-updates%</template>
|
||||||
|
</md-button>
|
||||||
</md-card-content>
|
</md-card-content>
|
||||||
</md-card>
|
</md-card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,7 +133,8 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { version, codename } from '../../../config';
|
import { apiUrl, version, codename, langs } from '../../../config';
|
||||||
|
import checkForUpdate from '../../../common/scripts/check-for-update';
|
||||||
|
|
||||||
import XProfile from './settings/settings.profile.vue';
|
import XProfile from './settings/settings.profile.vue';
|
||||||
|
|
||||||
|
@ -40,22 +145,44 @@ export default Vue.extend({
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
apiUrl,
|
||||||
version,
|
version,
|
||||||
codename,
|
codename,
|
||||||
darkmode: localStorage.getItem('darkmode') == 'true'
|
langs,
|
||||||
|
latestVersion: undefined,
|
||||||
|
checkingForUpdate: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
name(): string {
|
name(): string {
|
||||||
return Vue.filter('userName')((this as any).os.i);
|
return Vue.filter('userName')((this as any).os.i);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
darkmode: {
|
||||||
darkmode() {
|
get() { return this.$store.state.device.darkmode; },
|
||||||
(this as any)._updateDarkmode_(this.darkmode);
|
set(value) { this.$store.commit('device/set', { key: 'darkmode', value }); }
|
||||||
}
|
},
|
||||||
|
|
||||||
|
postStyle: {
|
||||||
|
get() { return this.$store.state.device.postStyle; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'postStyle', value }); }
|
||||||
|
},
|
||||||
|
|
||||||
|
lightmode: {
|
||||||
|
get() { return this.$store.state.device.lightmode; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'lightmode', value }); }
|
||||||
|
},
|
||||||
|
|
||||||
|
loadRawImages: {
|
||||||
|
get() { return this.$store.state.device.loadRawImages; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'loadRawImages', value }); }
|
||||||
|
},
|
||||||
|
|
||||||
|
lang: {
|
||||||
|
get() { return this.$store.state.device.lang; },
|
||||||
|
set(value) { this.$store.commit('device/set', { key: 'lang', value }); }
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -67,19 +194,83 @@ export default Vue.extend({
|
||||||
(this as any).os.signout();
|
(this as any).os.signout();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onChangeFetchOnScroll(v) {
|
||||||
|
this.$store.dispatch('settings/set', {
|
||||||
|
key: 'fetchOnScroll',
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onChangeDisableViaMobile(v) {
|
||||||
|
this.$store.dispatch('settings/set', {
|
||||||
|
key: 'disableViaMobile',
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onChangeLoadRemoteMedia(v) {
|
||||||
|
this.$store.dispatch('settings/set', {
|
||||||
|
key: 'loadRemoteMedia',
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
onChangeCircleIcons(v) {
|
onChangeCircleIcons(v) {
|
||||||
this.$store.dispatch('settings/set', {
|
this.$store.dispatch('settings/set', {
|
||||||
key: 'circleIcons',
|
key: 'circleIcons',
|
||||||
value: v
|
value: v
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onChangeShowReplyTarget(v) {
|
||||||
|
this.$store.dispatch('settings/set', {
|
||||||
|
key: 'showReplyTarget',
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onChangeShowMyRenotes(v) {
|
||||||
|
this.$store.dispatch('settings/set', {
|
||||||
|
key: 'showMyRenotes',
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onChangeShowRenotedMyNotes(v) {
|
||||||
|
this.$store.dispatch('settings/set', {
|
||||||
|
key: 'showRenotedMyNotes',
|
||||||
|
value: v
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
checkForUpdate() {
|
||||||
|
this.checkingForUpdate = true;
|
||||||
|
checkForUpdate((this as any).os, true, true).then(newer => {
|
||||||
|
this.checkingForUpdate = false;
|
||||||
|
this.latestVersion = newer;
|
||||||
|
if (newer == null) {
|
||||||
|
(this as any).apis.dialog({
|
||||||
|
title: '%i18n:@no-updates%',
|
||||||
|
text: '%i18n:@no-updates-desc%'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
(this as any).apis.dialog({
|
||||||
|
title: '%i18n:@update-available%',
|
||||||
|
text: '%i18n:@update-available-desc%'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
main
|
root(isDark)
|
||||||
padding 0 16px
|
padding 0 16px
|
||||||
|
margin 0 auto
|
||||||
|
max-width 500px
|
||||||
|
width 100%
|
||||||
|
|
||||||
> div
|
> div
|
||||||
> *
|
> *
|
||||||
|
@ -89,57 +280,12 @@ main
|
||||||
display block
|
display block
|
||||||
margin 24px
|
margin 24px
|
||||||
text-align center
|
text-align center
|
||||||
color #cad2da
|
color isDark ? #cad2da : #a2a9b1
|
||||||
|
|
||||||
> ul
|
main[data-darkmode]
|
||||||
$radius = 8px
|
root(true)
|
||||||
|
|
||||||
display block
|
main:not([data-darkmode])
|
||||||
margin 16px auto
|
root(false)
|
||||||
padding 0
|
|
||||||
max-width 500px
|
|
||||||
width calc(100% - 32px)
|
|
||||||
list-style none
|
|
||||||
background #fff
|
|
||||||
border solid 1px rgba(#000, 0.2)
|
|
||||||
border-radius $radius
|
|
||||||
|
|
||||||
> li
|
|
||||||
display block
|
|
||||||
border-bottom solid 1px #ddd
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background rgba(#000, 0.1)
|
|
||||||
|
|
||||||
&:first-child
|
|
||||||
border-top-left-radius $radius
|
|
||||||
border-top-right-radius $radius
|
|
||||||
|
|
||||||
&:last-child
|
|
||||||
border-bottom-left-radius $radius
|
|
||||||
border-bottom-right-radius $radius
|
|
||||||
border-bottom none
|
|
||||||
|
|
||||||
> a
|
|
||||||
$height = 48px
|
|
||||||
|
|
||||||
display block
|
|
||||||
position relative
|
|
||||||
padding 0 16px
|
|
||||||
line-height $height
|
|
||||||
color #4d635e
|
|
||||||
|
|
||||||
> [data-fa]:nth-of-type(1)
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> [data-fa]:nth-of-type(2)
|
|
||||||
display block
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
right 8px
|
|
||||||
z-index 1
|
|
||||||
padding 0 20px
|
|
||||||
font-size 1.2em
|
|
||||||
line-height $height
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,50 +1,55 @@
|
||||||
<template>
|
<template>
|
||||||
<md-card class="md-layout-item md-size-50 md-small-size-100">
|
<md-card>
|
||||||
<md-card-header>
|
<md-card-header>
|
||||||
<div class="md-title">%i18n:@title%</div>
|
<div class="md-title">%fa:pencil-alt% %i18n:@title%</div>
|
||||||
</md-card-header>
|
</md-card-header>
|
||||||
|
|
||||||
<md-card-content>
|
<md-card-content>
|
||||||
<md-field>
|
<md-field>
|
||||||
<label>%i18n:@name%</label>
|
<label>%i18n:@name%</label>
|
||||||
<md-input v-model="name" :disabled="saving"/>
|
<md-input v-model="name" :disabled="saving" md-counter="30"/>
|
||||||
</md-field>
|
</md-field>
|
||||||
|
|
||||||
<md-field>
|
<md-field>
|
||||||
|
<label>%i18n:@account%</label>
|
||||||
|
<span class="md-prefix">@</span>
|
||||||
|
<md-input v-model="username" readonly></md-input>
|
||||||
|
<span class="md-suffix">@{{ host }}</span>
|
||||||
|
</md-field>
|
||||||
|
|
||||||
|
<md-field>
|
||||||
|
<md-icon>%fa:map-marker-alt%</md-icon>
|
||||||
<label>%i18n:@location%</label>
|
<label>%i18n:@location%</label>
|
||||||
<md-input v-model="location" :disabled="saving"/>
|
<md-input v-model="location" :disabled="saving"/>
|
||||||
</md-field>
|
</md-field>
|
||||||
|
|
||||||
<md-field>
|
<md-field>
|
||||||
<label>%i18n:@description%</label>
|
<md-icon>%fa:birthday-cake%</md-icon>
|
||||||
<md-textarea v-model="description" :disabled="saving"/>
|
|
||||||
</md-field>
|
|
||||||
|
|
||||||
<md-field>
|
|
||||||
<label>%i18n:@birthday%</label>
|
<label>%i18n:@birthday%</label>
|
||||||
<md-input type="date" v-model="birthday" :disabled="saving"/>
|
<md-input type="date" v-model="birthday" :disabled="saving"/>
|
||||||
</md-field>
|
</md-field>
|
||||||
|
|
||||||
<div>
|
<md-field>
|
||||||
<div class="md-body-2">%i18n:@avatar%</div>
|
<label>%i18n:@description%</label>
|
||||||
<md-menu md-direction="bottom-end" :md-close-on-select="true">
|
<md-textarea v-model="description" :disabled="saving" md-counter="500"/>
|
||||||
<md-button md-menu-trigger>%i18n:@set-avatar%</md-button>
|
</md-field>
|
||||||
<md-menu-content>
|
|
||||||
<md-menu-item @click="uploadAvatar">%i18n:@upload-avatar%</md-menu-item>
|
<md-field>
|
||||||
<md-menu-item @click="chooseAvatar">%i18n:@choose-avatar%</md-menu-item>
|
<label>%i18n:@avatar%</label>
|
||||||
</md-menu-content>
|
<md-file @md-change="onAvatarChange"/>
|
||||||
</md-menu>
|
</md-field>
|
||||||
</div>
|
|
||||||
|
<md-field>
|
||||||
|
<label>%i18n:@banner%</label>
|
||||||
|
<md-file @md-change="onBannerChange"/>
|
||||||
|
</md-field>
|
||||||
|
|
||||||
|
<md-dialog-alert
|
||||||
|
:md-active.sync="uploading"
|
||||||
|
md-content="%18n:!@uploading%"/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="md-body-2">%i18n:@banner%</div>
|
<md-switch v-model="isCat">%i18n:@is-cat%</md-switch>
|
||||||
<md-menu md-direction="bottom-end" :md-close-on-select="true">
|
|
||||||
<md-button md-menu-trigger>%i18n:@set-banner%</md-button>
|
|
||||||
<md-menu-content>
|
|
||||||
<md-menu-item @click="uploadAvatar">%i18n:@upload-banner%</md-menu-item>
|
|
||||||
<md-menu-item @click="chooseAvatar">%i18n:@choose-banner%</md-menu-item>
|
|
||||||
</md-menu-content>
|
|
||||||
</md-menu>
|
|
||||||
</div>
|
</div>
|
||||||
</md-card-content>
|
</md-card-content>
|
||||||
|
|
||||||
|
@ -56,58 +61,83 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { apiUrl, host } from '../../../../config';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
host,
|
||||||
name: null,
|
name: null,
|
||||||
|
username: null,
|
||||||
location: null,
|
location: null,
|
||||||
description: null,
|
description: null,
|
||||||
birthday: null,
|
birthday: null,
|
||||||
saving: false
|
avatarId: null,
|
||||||
|
bannerId: null,
|
||||||
|
isBot: false,
|
||||||
|
isCat: false,
|
||||||
|
saving: false,
|
||||||
|
uploading: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.name = (this as any).os.i.name || '';
|
this.name = (this as any).os.i.name || '';
|
||||||
|
this.username = (this as any).os.i.username;
|
||||||
this.location = (this as any).os.i.profile.location;
|
this.location = (this as any).os.i.profile.location;
|
||||||
this.description = (this as any).os.i.description;
|
this.description = (this as any).os.i.description;
|
||||||
this.birthday = (this as any).os.i.profile.birthday;
|
this.birthday = (this as any).os.i.profile.birthday;
|
||||||
|
this.avatarId = (this as any).os.i.avatarId;
|
||||||
|
this.bannerId = (this as any).os.i.bannerId;
|
||||||
|
this.isBot = (this as any).os.i.isBot;
|
||||||
|
this.isCat = (this as any).os.i.isCat;
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
chooseAvatar() {
|
onAvatarChange([file]) {
|
||||||
(this as any).apis.chooseDriveFile({
|
this.uploading = true;
|
||||||
multiple: false
|
|
||||||
}).then(file => {
|
|
||||||
this.avatarSaving = true;
|
|
||||||
|
|
||||||
(this as any).api('i/update', {
|
const data = new FormData();
|
||||||
avatarId: file.id
|
data.append('file', file);
|
||||||
}).then(() => {
|
data.append('i', (this as any).os.i.token);
|
||||||
this.avatarSaving = false;
|
|
||||||
alert('%i18n:!@avatar-saved%');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
chooseBanner() {
|
|
||||||
(this as any).apis.chooseDriveFile({
|
|
||||||
multiple: false
|
|
||||||
}).then(file => {
|
|
||||||
this.bannerSaving = true;
|
|
||||||
|
|
||||||
(this as any).api('i/update', {
|
fetch(apiUrl + '/drive/files/create', {
|
||||||
bannerId: file.id
|
method: 'POST',
|
||||||
}).then(() => {
|
body: data
|
||||||
this.bannerSaving = false;
|
})
|
||||||
alert('%i18n:!@banner-saved%');
|
.then(response => response.json())
|
||||||
});
|
.then(f => {
|
||||||
|
this.avatarId = f.id;
|
||||||
|
this.uploading = false;
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this.uploading = false;
|
||||||
|
alert('%18n:!@upload-failed%');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
uploadAvatar() {
|
|
||||||
// a
|
onBannerChange([file]) {
|
||||||
},
|
this.uploading = true;
|
||||||
uploadBanner() {
|
|
||||||
// a
|
const data = new FormData();
|
||||||
|
data.append('file', file);
|
||||||
|
data.append('i', (this as any).os.i.token);
|
||||||
|
|
||||||
|
fetch(apiUrl + '/drive/files/create', {
|
||||||
|
method: 'POST',
|
||||||
|
body: data
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(f => {
|
||||||
|
this.bannerId = f.id;
|
||||||
|
this.uploading = false;
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this.uploading = false;
|
||||||
|
alert('%18n:!@upload-failed%');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
this.saving = true;
|
this.saving = true;
|
||||||
|
|
||||||
|
@ -115,10 +145,19 @@ export default Vue.extend({
|
||||||
name: this.name || null,
|
name: this.name || null,
|
||||||
location: this.location || null,
|
location: this.location || null,
|
||||||
description: this.description || null,
|
description: this.description || null,
|
||||||
birthday: this.birthday || null
|
birthday: this.birthday || null,
|
||||||
}).then(() => {
|
avatarId: this.avatarId,
|
||||||
|
bannerId: this.bannerId,
|
||||||
|
isBot: this.isBot,
|
||||||
|
isCat: this.isCat
|
||||||
|
}).then(i => {
|
||||||
this.saving = false;
|
this.saving = false;
|
||||||
alert('%i18n:!@saved%');
|
(this as any).os.i.avatarId = i.avatarId;
|
||||||
|
(this as any).os.i.avatarUrl = i.avatarUrl;
|
||||||
|
(this as any).os.i.bannerId = i.bannerId;
|
||||||
|
(this as any).os.i.bannerUrl = i.bannerUrl;
|
||||||
|
|
||||||
|
alert('%i18n:@saved%');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue