diff --git a/Dockerfile b/Dockerfile index 7b159efe09..9eb69e2302 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ RUN apk add --no-cache \ autoconf \ automake \ file \ + git \ g++ \ gcc \ libc-dev \ diff --git a/README.md b/README.md index 263e7b44ca..0ed7a36bef 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![CircleCI](https://img.shields.io/circleci/project/github/syuilo/misskey.svg?style=for-the-badge&logo=circleci)](https://circleci.com/gh/syuilo/misskey) [![Dependencies](https://img.shields.io/david/syuilo/misskey.svg?style=for-the-badge&logo=npm)](https://david-dm.org/syuilo/misskey) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge&logo=github)](http://makeapullrequest.com) +[![Awesome Humane Tech](https://raw.githubusercontent.com/humanetech-community/awesome-humane-tech/main/humane-tech-badge.svg?sanitize=true)](https://github.com/humanetech-community/awesome-humane-tech) **A forever evolving, sophisticated microblogging platform.** diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index d3891a41a6..870041d673 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -264,6 +264,7 @@ rename: "名前を変更" avatar: "アイコン" banner: "バナー" nsfw: "閲覧注意" +whenServerDisconnected: "サーバーとの接続が失われたとき" disconnectedFromServer: "サーバーから切断されました" reload: "リロード" doNothing: "なにもしない" @@ -364,7 +365,6 @@ unregister: "登録を解除" passwordLessLogin: "パスワード無しログイン" resetPassword: "パスワードをリセット" newPasswordIs: "新しいパスワードは「{password}」です" -autoReloadWhenDisconnected: "サーバー切断時に自動リロード" autoNoteWatch: "ノートの自動ウォッチ" autoNoteWatchDescription: "あなたがリアクションしたり返信したりした他のユーザーのノートに関する通知を受け取るようにします。" reduceUiAnimation: "UIのアニメーションを減らす" @@ -468,6 +468,7 @@ objectStorageUseSSL: "SSLを使用する" objectStorageUseSSLDesc: "API接続にhttpsを使用しない場合はオフにしてください" objectStorageUseProxy: "Proxyを利用する" objectStorageUseProxyDesc: "API接続にproxyを利用しない場合はオフにしてください" +objectStorageSetPublicRead: "アップロード時に'public-read'を設定する" serverLogs: "サーバーログ" deleteAll: "全て削除" showFixedPostForm: "タイムライン上部に投稿フォームを表示する" @@ -558,6 +559,29 @@ userSaysSomething: "{name}が何かを言いました" makeActive: "アクティブにする" display: "表示" copy: "コピー" +metrics: "メトリクス" +overview: "概要" +logs: "ログ" +delayed: "遅延" +database: "データベース" +channel: "チャンネル" +create: "作成" + +_serverDisconnectedBehavior: + reload: "自動でリロード" + dialog: "ダイアログで警告" + quiet: "控えめに警告" + +_channel: + create: "チャンネルを作成" + edit: "チャンネルを編集" + setBanner: "バナーを設定" + removeBanner: "バナーを削除" + featured: "トレンド" + owned: "管理中" + following: "フォロー中" + usersCount: "{n}人が参加中" + notesCount: "{n}投稿があります" _sidebar: full: "フル" @@ -572,6 +596,7 @@ _wordMute: hardDescription: "指定した条件のノートをタイムラインに追加しないようにします。追加されなかったノートは、条件を変更しても除外されたままになります。" soft: "ソフト" hard: "ハード" + mutedNotes: "ミュートされたノート" _theme: explore: "テーマを探す" @@ -653,6 +678,7 @@ _sfx: chat: "チャット" chatBg: "チャット(バックグラウンド)" antenna: "アンテナ受信" + channel: "チャンネル通知" _ago: unknown: "謎" @@ -733,6 +759,8 @@ _permissions: "write:page-likes": "ページのいいねを操作する" "read:user-groups": "ユーザーグループを見る" "write:user-groups": "ユーザーグループを操作する" + "read:channels": "チャンネルを見る" + "write:channels": "チャンネルを操作する" _auth: shareAccess: "「{name}」がアカウントにアクセスすることを許可しますか?" @@ -815,6 +843,7 @@ _visibility: _postForm: replyPlaceholder: "このノートに返信..." quotePlaceholder: "このノートを引用..." + channelPlaceholder: "チャンネルに投稿..." _placeholders: a: "いまどうしてる?" b: "何かありましたか?" diff --git a/migration/1596548170836-channel.ts b/migration/1596548170836-channel.ts new file mode 100644 index 0000000000..4e3ebb330a --- /dev/null +++ b/migration/1596548170836-channel.ts @@ -0,0 +1,58 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class channel1596548170836 implements MigrationInterface { + name = 'channel1596548170836' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "channel" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "lastNotedAt" TIMESTAMP WITH TIME ZONE, "userId" character varying(32) NOT NULL, "name" character varying(128) NOT NULL, "description" character varying(2048), "bannerId" character varying(32), "notesCount" integer NOT NULL DEFAULT 0, "usersCount" integer NOT NULL DEFAULT 0, CONSTRAINT "PK_590f33ee6ee7d76437acf362e39" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_71cb7b435b7c0d4843317e7e16" ON "channel" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_29ef80c6f13bcea998447fce43" ON "channel" ("lastNotedAt") `); + await queryRunner.query(`CREATE INDEX "IDX_823bae55bd81b3be6e05cff438" ON "channel" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_0f58c11241e649d2a638a8de94" ON "channel" ("notesCount") `); + await queryRunner.query(`CREATE INDEX "IDX_094b86cd36bb805d1aa1e8cc9a" ON "channel" ("usersCount") `); + await queryRunner.query(`CREATE TABLE "channel_following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, CONSTRAINT "PK_8b104be7f7415113f2a02cd5bdd" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_11e71f2511589dcc8a4d3214f9" ON "channel_following" ("createdAt") `); + await queryRunner.query(`CREATE INDEX "IDX_0e43068c3f92cab197c3d3cd86" ON "channel_following" ("followeeId") `); + await queryRunner.query(`CREATE INDEX "IDX_6d8084ec9496e7334a4602707e" ON "channel_following" ("followerId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_2e230dd45a10e671d781d99f3e" ON "channel_following" ("followerId", "followeeId") `); + await queryRunner.query(`CREATE TABLE "channel_note_pining" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "channelId" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, CONSTRAINT "PK_44f7474496bcf2e4b741681146d" PRIMARY KEY ("id"))`); + await queryRunner.query(`CREATE INDEX "IDX_8125f950afd3093acb10d2db8a" ON "channel_note_pining" ("channelId") `); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_f36fed37d6d4cdcc68c803cd9c" ON "channel_note_pining" ("channelId", "noteId") `); + await queryRunner.query(`ALTER TABLE "note" ADD "channelId" character varying(32) DEFAULT null`); + await queryRunner.query(`CREATE INDEX "IDX_f22169eb10657bded6d875ac8f" ON "note" ("channelId") `); + await queryRunner.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_823bae55bd81b3be6e05cff4383" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel" ADD CONSTRAINT "FK_999da2bcc7efadbfe0e92d3bc19" FOREIGN KEY ("bannerId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "note" ADD CONSTRAINT "FK_f22169eb10657bded6d875ac8f9" FOREIGN KEY ("channelId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_following" ADD CONSTRAINT "FK_0e43068c3f92cab197c3d3cd86e" FOREIGN KEY ("followeeId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_following" ADD CONSTRAINT "FK_6d8084ec9496e7334a4602707e1" FOREIGN KEY ("followerId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_note_pining" ADD CONSTRAINT "FK_8125f950afd3093acb10d2db8a8" FOREIGN KEY ("channelId") REFERENCES "channel"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + await queryRunner.query(`ALTER TABLE "channel_note_pining" ADD CONSTRAINT "FK_10b19ef67d297ea9de325cd4502" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "channel_note_pining" DROP CONSTRAINT "FK_10b19ef67d297ea9de325cd4502"`); + await queryRunner.query(`ALTER TABLE "channel_note_pining" DROP CONSTRAINT "FK_8125f950afd3093acb10d2db8a8"`); + await queryRunner.query(`ALTER TABLE "channel_following" DROP CONSTRAINT "FK_6d8084ec9496e7334a4602707e1"`); + await queryRunner.query(`ALTER TABLE "channel_following" DROP CONSTRAINT "FK_0e43068c3f92cab197c3d3cd86e"`); + await queryRunner.query(`ALTER TABLE "note" DROP CONSTRAINT "FK_f22169eb10657bded6d875ac8f9"`); + await queryRunner.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_999da2bcc7efadbfe0e92d3bc19"`); + await queryRunner.query(`ALTER TABLE "channel" DROP CONSTRAINT "FK_823bae55bd81b3be6e05cff4383"`); + await queryRunner.query(`DROP INDEX "IDX_f22169eb10657bded6d875ac8f"`); + await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "channelId"`); + await queryRunner.query(`DROP INDEX "IDX_f36fed37d6d4cdcc68c803cd9c"`); + await queryRunner.query(`DROP INDEX "IDX_8125f950afd3093acb10d2db8a"`); + await queryRunner.query(`DROP TABLE "channel_note_pining"`); + await queryRunner.query(`DROP INDEX "IDX_2e230dd45a10e671d781d99f3e"`); + await queryRunner.query(`DROP INDEX "IDX_6d8084ec9496e7334a4602707e"`); + await queryRunner.query(`DROP INDEX "IDX_0e43068c3f92cab197c3d3cd86"`); + await queryRunner.query(`DROP INDEX "IDX_11e71f2511589dcc8a4d3214f9"`); + await queryRunner.query(`DROP TABLE "channel_following"`); + await queryRunner.query(`DROP INDEX "IDX_094b86cd36bb805d1aa1e8cc9a"`); + await queryRunner.query(`DROP INDEX "IDX_0f58c11241e649d2a638a8de94"`); + await queryRunner.query(`DROP INDEX "IDX_823bae55bd81b3be6e05cff438"`); + await queryRunner.query(`DROP INDEX "IDX_29ef80c6f13bcea998447fce43"`); + await queryRunner.query(`DROP INDEX "IDX_71cb7b435b7c0d4843317e7e16"`); + await queryRunner.query(`DROP TABLE "channel"`); + } + +} diff --git a/migration/1596786425167-channel2.ts b/migration/1596786425167-channel2.ts new file mode 100644 index 0000000000..0233f7ab0f --- /dev/null +++ b/migration/1596786425167-channel2.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class channel21596786425167 implements MigrationInterface { + name = 'channel21596786425167' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "channel_following" ADD "readCursor" TIMESTAMP WITH TIME ZONE NOT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "channel_following" DROP COLUMN "readCursor"`); + } + +} diff --git a/migration/1597230137744-objectStorageSetPublicRead.ts b/migration/1597230137744-objectStorageSetPublicRead.ts new file mode 100644 index 0000000000..f040f2afdd --- /dev/null +++ b/migration/1597230137744-objectStorageSetPublicRead.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class objectStorageSetPublicRead1597230137744 implements MigrationInterface { + name = 'objectStorageSetPublicRead1597230137744' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "meta" ADD "objectStorageSetPublicRead" boolean NOT NULL DEFAULT false`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "objectStorageSetPublicRead"`); + } + +} diff --git a/migration/1597385880794-add-sensitive-index.ts b/migration/1597385880794-add-sensitive-index.ts new file mode 100644 index 0000000000..ff6251ac0a --- /dev/null +++ b/migration/1597385880794-add-sensitive-index.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class addSensitiveIndex1597385880794 implements MigrationInterface { + name = 'addSensitiveIndex1597385880794' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE INDEX "IDX_a7eba67f8b3fa27271e85d2e26" ON "drive_file" ("isSensitive") `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_a7eba67f8b3fa27271e85d2e26"`); + } + +} diff --git a/migration/1597459042300-channel-unread.ts b/migration/1597459042300-channel-unread.ts new file mode 100644 index 0000000000..a0f862114d --- /dev/null +++ b/migration/1597459042300-channel-unread.ts @@ -0,0 +1,27 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class channelUnread1597459042300 implements MigrationInterface { + name = 'channelUnread1597459042300' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`TRUNCATE TABLE "note_unread"`, undefined); + await queryRunner.query(`ALTER TABLE "channel_following" DROP COLUMN "readCursor"`); + await queryRunner.query(`ALTER TABLE "note_unread" ADD "isMentioned" boolean NOT NULL`); + await queryRunner.query(`ALTER TABLE "note_unread" ADD "noteChannelId" character varying(32)`); + await queryRunner.query(`CREATE INDEX "IDX_25b1dd384bec391b07b74b861c" ON "note_unread" ("isMentioned") `); + await queryRunner.query(`CREATE INDEX "IDX_89a29c9237b8c3b6b3cbb4cb30" ON "note_unread" ("isSpecified") `); + await queryRunner.query(`CREATE INDEX "IDX_29e8c1d579af54d4232939f994" ON "note_unread" ("noteUserId") `); + await queryRunner.query(`CREATE INDEX "IDX_6a57f051d82c6d4036c141e107" ON "note_unread" ("noteChannelId") `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_6a57f051d82c6d4036c141e107"`); + await queryRunner.query(`DROP INDEX "IDX_29e8c1d579af54d4232939f994"`); + await queryRunner.query(`DROP INDEX "IDX_89a29c9237b8c3b6b3cbb4cb30"`); + await queryRunner.query(`DROP INDEX "IDX_25b1dd384bec391b07b74b861c"`); + await queryRunner.query(`ALTER TABLE "note_unread" DROP COLUMN "noteChannelId"`); + await queryRunner.query(`ALTER TABLE "note_unread" DROP COLUMN "isMentioned"`); + await queryRunner.query(`ALTER TABLE "channel_following" ADD "readCursor" TIMESTAMP WITH TIME ZONE NOT NULL`); + } + +} diff --git a/src/client/assets/sounds/noizenecio/kick_gaba2.mp3 b/src/client/assets/sounds/noizenecio/kick_gaba2.mp3 new file mode 100644 index 0000000000..33c2837620 Binary files /dev/null and b/src/client/assets/sounds/noizenecio/kick_gaba2.mp3 differ diff --git a/src/client/assets/sounds/syuilo/reverved.mp3 b/src/client/assets/sounds/syuilo/reverved.mp3 new file mode 100644 index 0000000000..47588ef270 Binary files /dev/null and b/src/client/assets/sounds/syuilo/reverved.mp3 differ diff --git a/src/client/assets/sounds/syuilo/ryukyu.mp3 b/src/client/assets/sounds/syuilo/ryukyu.mp3 new file mode 100644 index 0000000000..9e935e3f37 Binary files /dev/null and b/src/client/assets/sounds/syuilo/ryukyu.mp3 differ diff --git a/src/client/assets/sounds/syuilo/square-pico.mp3 b/src/client/assets/sounds/syuilo/square-pico.mp3 new file mode 100644 index 0000000000..c4d8305ae7 Binary files /dev/null and b/src/client/assets/sounds/syuilo/square-pico.mp3 differ diff --git a/src/client/components/channel-follow-button.vue b/src/client/components/channel-follow-button.vue new file mode 100644 index 0000000000..3b83865b55 --- /dev/null +++ b/src/client/components/channel-follow-button.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/src/client/components/channel-preview.vue b/src/client/components/channel-preview.vue new file mode 100644 index 0000000000..bef4759570 --- /dev/null +++ b/src/client/components/channel-preview.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/client/components/instance-stats.vue b/src/client/components/instance-stats.vue index 59ea57f61b..5f6e963ece 100644 --- a/src/client/components/instance-stats.vue +++ b/src/client/components/instance-stats.vue @@ -1,5 +1,5 @@ @@ -401,13 +401,11 @@ export default defineComponent({ > .save { margin: 6px 0 0 0; - font-size: 13px; + font-size: 0.8em; } > .desc { margin: 6px 0 0 0; - font-size: 13px; - opacity: 0.7; &:empty { display: none; diff --git a/src/client/components/ui/select.vue b/src/client/components/ui/select.vue index 271989f2df..66a4de13d6 100644 --- a/src/client/components/ui/select.vue +++ b/src/client/components/ui/select.vue @@ -196,7 +196,7 @@ export default defineComponent({ > .text { margin: 6px 0; - font-size: 13px; + font-size: 0.8em; &:empty { display: none; diff --git a/src/client/components/ui/textarea.vue b/src/client/components/ui/textarea.vue index 30accf8ffd..ee5ac89f27 100644 --- a/src/client/components/ui/textarea.vue +++ b/src/client/components/ui/textarea.vue @@ -14,7 +14,7 @@ > -
+
@@ -163,13 +163,11 @@ export default defineComponent({ > .save { margin: 6px 0 0 0; - font-size: 13px; + font-size: 0.8em; } > .desc { margin: 6px 0 0 0; - font-size: 13px; - opacity: 0.7; &:empty { display: none; diff --git a/src/client/components/url-preview.vue b/src/client/components/url-preview.vue index 93f901027c..b5cdd087f1 100644 --- a/src/client/components/url-preview.vue +++ b/src/client/components/url-preview.vue @@ -6,7 +6,7 @@ -
+
diff --git a/src/client/default.vue b/src/client/default.vue index d63c89e963..83c62fda23 100644 --- a/src/client/default.vue +++ b/src/client/default.vue @@ -33,7 +33,7 @@ -
+
@@ -549,6 +549,18 @@ export default defineComponent({ backdrop-filter: blur(4px); } + &.full { + width: 100%; + + > main { + width: 100%; + } + + > .widgets { + display: none; + } + } + > main { width: $main-width; min-width: 0; diff --git a/src/client/directives/size.ts b/src/client/directives/size.ts index 0604a797c0..352f825afe 100644 --- a/src/client/directives/size.ts +++ b/src/client/directives/size.ts @@ -3,27 +3,12 @@ import { Directive } from 'vue'; //const observers = new Map(); export default { - mounted(el, binding, vn) { + mounted(src, binding, vn) { const query = binding.value; - /* - const addClassRecursive = (el: Element, cls: string) => { - el.classList.add(cls); - if (el.children) { - for (const child of el.children) { - addClassRecursive(child, cls); - } - } - }; - - const removeClassRecursive = (el: Element, cls: string) => { - el.classList.remove(cls); - if (el.children) { - for (const child of el.children) { - removeClassRecursive(child, cls); - } - } - };*/ + // TODO: 要素をもらうというよりはカスタム幅算出関数をもらうようにしてcalcで都度呼び出して計算するようにした方が柔軟そう + // その場合はunbindの方も改修することを忘れずに + const el = query.el ? query.el() : src; const addClass = (el: Element, cls: string) => { el.classList.add(cls); @@ -36,19 +21,21 @@ export default { const calc = () => { const width = el.clientWidth; - for (const q of query) { - if (q.max) { - if (width <= q.max) { - addClass(el, 'max-width_' + q.max + 'px'); + if (query.max) { + for (const v of query.max) { + if (width <= v) { + addClass(src, 'max-width_' + v + 'px'); } else { - removeClass(el, 'max-width_' + q.max + 'px'); + removeClass(src, 'max-width_' + v + 'px'); } } - if (q.min) { - if (width >= q.min) { - addClass(el, 'min-width_' + q.min + 'px'); + } + if (query.min) { + for (const v of query.min) { + if (width >= v) { + addClass(src, 'min-width_' + v + 'px'); } else { - removeClass(el, 'min-width_' + q.min + 'px'); + removeClass(src, 'min-width_' + v + 'px'); } } } @@ -71,7 +58,11 @@ export default { el._ro_ = ro; }, - unmounted(el, binding, vn) { + unmounted(src, binding, vn) { + const query = binding.value; + + const el = query.el ? query.el() : src; + el._ro_.unobserve(el); } } as Directive; diff --git a/src/client/init.ts b/src/client/init.ts index 03eee450c7..4083fe501a 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -217,6 +217,25 @@ store.watch(state => state.device.useBlurEffectForModal, v => { document.documentElement.style.setProperty('--modalBgFilter', v ? 'blur(4px)' : 'none'); }, { immediate: true }); +let reloadDialogShowing = false; +stream.on('_disconnected_', async () => { + if (store.state.device.serverDisconnectedBehavior === 'reload') { + location.reload(); + } else if (store.state.device.serverDisconnectedBehavior === 'dialog') { + if (reloadDialogShowing) return; + reloadDialogShowing = true; + const { canceled } = await app.dialog({ + type: 'warning', + title: app.$t('disconnectedFromServer'), + text: app.$t('reloadConfirm'), + showCancelButton: true + }); + reloadDialogShowing = false; + if (!canceled) { + location.reload(); + } + } +}); stream.on('emojiAdded', data => { // TODO @@ -337,6 +356,26 @@ if (store.getters.isSignedIn) { }); }); + main.on('readAllChannels', () => { + store.dispatch('mergeMe', { + hasUnreadChannel: false + }); + }); + + main.on('unreadChannel', () => { + store.dispatch('mergeMe', { + hasUnreadChannel: true + }); + + app.sound('channel'); + }); + + main.on('readAllAnnouncements', () => { + store.dispatch('mergeMe', { + hasUnreadAnnouncement: false + }); + }); + main.on('clientSettingUpdated', x => { store.commit('settings/set', { key: x.key, diff --git a/src/client/pages/channel-editor.vue b/src/client/pages/channel-editor.vue new file mode 100644 index 0000000000..0178662119 --- /dev/null +++ b/src/client/pages/channel-editor.vue @@ -0,0 +1,128 @@ + + + + + diff --git a/src/client/pages/channel.vue b/src/client/pages/channel.vue new file mode 100644 index 0000000000..69631af74b --- /dev/null +++ b/src/client/pages/channel.vue @@ -0,0 +1,190 @@ + + + + + diff --git a/src/client/pages/channels.vue b/src/client/pages/channels.vue new file mode 100644 index 0000000000..85804141f1 --- /dev/null +++ b/src/client/pages/channels.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/src/client/pages/index.home.vue b/src/client/pages/index.home.vue index 8028040897..45d613162d 100644 --- a/src/client/pages/index.home.vue +++ b/src/client/pages/index.home.vue @@ -2,14 +2,15 @@
@@ -19,13 +20,13 @@ - +
diff --git a/src/client/pages/instance/index.vue b/src/client/pages/instance/index.vue index 0ba5d763b0..2e2bd0c3fc 100644 --- a/src/client/pages/instance/index.vue +++ b/src/client/pages/instance/index.vue @@ -1,113 +1,204 @@ diff --git a/src/client/pages/instance/federation.instance.vue b/src/client/pages/instance/instance.vue similarity index 80% rename from src/client/pages/instance/federation.instance.vue rename to src/client/pages/instance/instance.vue index c51303942d..81312a0cf3 100644 --- a/src/client/pages/instance/federation.instance.vue +++ b/src/client/pages/instance/instance.vue @@ -2,69 +2,69 @@
-
-
-
-
{{ $t('software') }}
-
{{ instance.softwareName || '?' }}
+
+
+
+
{{ $t('software') }}
+
{{ instance.softwareName || '?' }}
-
-
{{ $t('version') }}
-
{{ instance.softwareVersion || '?' }}
+
+
{{ $t('version') }}
+
{{ instance.softwareVersion || '?' }}
-
-
-
-
{{ $t('registeredAt') }}
-
{{ new Date(instance.caughtAt).toLocaleString() }} ()
+
+
+
+
{{ $t('registeredAt') }}
+
{{ new Date(instance.caughtAt).toLocaleString() }} ()
-
-
-
{{ $t('following') }}
-
{{ number(instance.followingCount) }}
+
+
+
{{ $t('following') }}
+
-
-
{{ $t('followers') }}
-
{{ number(instance.followersCount) }}
+
+
{{ $t('followers') }}
+
-
-
-
{{ $t('users') }}
-
{{ number(instance.usersCount) }}
+
+
+
{{ $t('users') }}
+
-
-
{{ $t('notes') }}
-
{{ number(instance.notesCount) }}
+
+
{{ $t('notes') }}
+
{{ number(instance.notesCount) }}
-
-
-
{{ $t('files') }}
-
{{ number(instance.driveFiles) }}
+
+
+
{{ $t('files') }}
+
{{ number(instance.driveFiles) }}
-
-
{{ $t('storageUsage') }}
-
{{ bytes(instance.driveUsage) }}
+
+
{{ $t('storageUsage') }}
+
{{ bytes(instance.driveUsage) }}
-
-
-
{{ $t('latestRequestSentAt') }}
-
N/A
+
+
+
{{ $t('latestRequestSentAt') }}
+
N/A
-
-
{{ $t('latestStatus') }}
-
{{ instance.latestStatus ? instance.latestStatus : 'N/A' }}
+
+
{{ $t('latestStatus') }}
+
{{ instance.latestStatus ? instance.latestStatus : 'N/A' }}
-
-
-
{{ $t('latestRequestReceivedAt') }}
-
N/A
+
+
+
{{ $t('latestRequestReceivedAt') }}
+
N/A
@@ -489,39 +489,12 @@ export default defineComponent({ .mk-instance-info { overflow: auto; - > .table { + > ._table { padding: 0 32px; @media (max-width: 500px) { padding: 0 16px; } - - > .row { - display: flex; - - &:not(:last-child) { - margin-bottom: 8px; - } - - > .cell { - flex: 1; - - > .label { - font-size: 80%; - opacity: 0.7; - - > .icon { - margin-right: 4px; - display: none; - } - } - - > .data.clickable { - color: var(--accent); - cursor: pointer; - } - } - } } > .data { diff --git a/src/client/pages/instance/queue.queue.vue b/src/client/pages/instance/queue.chart.vue similarity index 83% rename from src/client/pages/instance/queue.queue.vue rename to src/client/pages/instance/queue.chart.vue index e020cfc095..1e61478e6a 100644 --- a/src/client/pages/instance/queue.queue.vue +++ b/src/client/pages/instance/queue.chart.vue @@ -1,11 +1,13 @@
-
+
{{ $t('proxyAccount') }}
{{ $t('proxyAccount') }} @@ -176,7 +177,7 @@
-
+
{{ $t('blockedInstances') }}
@@ -188,7 +189,7 @@
-
+
{{ $t('integration') }}
Twitter
@@ -221,7 +222,8 @@ {{ $t('save') }}
-
+ +
Summaly Proxy
URL @@ -305,6 +307,7 @@ export default defineComponent({ objectStorageSecretKey: null, objectStorageUseSSL: false, objectStorageUseProxy: false, + objectStorageSetPublicRead: false, enableTwitterIntegration: false, twitterConsumerKey: null, twitterConsumerSecret: null, @@ -372,6 +375,7 @@ export default defineComponent({ this.objectStorageSecretKey = this.meta.objectStorageSecretKey; this.objectStorageUseSSL = this.meta.objectStorageUseSSL; this.objectStorageUseProxy = this.meta.objectStorageUseProxy; + this.objectStorageSetPublicRead = this.meta.objectStorageSetPublicRead; this.enableTwitterIntegration = this.meta.enableTwitterIntegration; this.twitterConsumerKey = this.meta.twitterConsumerKey; this.twitterConsumerSecret = this.meta.twitterConsumerSecret; @@ -521,6 +525,7 @@ export default defineComponent({ objectStorageSecretKey: this.objectStorageSecretKey ? this.objectStorageSecretKey : null, objectStorageUseSSL: this.objectStorageUseSSL, objectStorageUseProxy: this.objectStorageUseProxy, + objectStorageSetPublicRead: this.objectStorageSetPublicRead, enableTwitterIntegration: this.enableTwitterIntegration, twitterConsumerKey: this.twitterConsumerKey, twitterConsumerSecret: this.twitterConsumerSecret, diff --git a/src/client/pages/instance/users.vue b/src/client/pages/instance/users.vue index 7705c9a745..0167d7aa24 100644 --- a/src/client/pages/instance/users.vue +++ b/src/client/pages/instance/users.vue @@ -3,7 +3,7 @@ {{ $t('users') }} -
+
{{ $t('lookup') }}
@@ -16,7 +16,7 @@
-
+
{{ $t('users') }}
diff --git a/src/client/pages/messaging/index.vue b/src/client/pages/messaging/index.vue index 3edc630387..f5fac791a8 100644 --- a/src/client/pages/messaging/index.vue +++ b/src/client/pages/messaging/index.vue @@ -1,5 +1,5 @@