Compare commits

...

36 Commits

Author SHA1 Message Date
tamaina
7c9330a02f Release: 13.7.3
Merge pull request #10048 from misskey-dev/develop
2023-02-23 22:15:56 +09:00
syuilo
ca99468970 Update CONTRIBUTING.md 2023-02-23 20:49:09 +09:00
syuilo
8a5c6240b4 Merge branch 'master' into develop 2023-02-23 20:48:20 +09:00
syuilo
fca820c90c 13.7.3 2023-02-23 20:47:19 +09:00
tamaina
becc4d2e54 fix: i/notificationsで古い通知タイプを許容するなど、古い通知タイプの清算 (#10042)
* wip

* fix

* create migration

* oops

* fix front const

* changelog

* fix type

* fix

* wip

* Revert "wip"

This reverts commit 6cdb3600e2.

* enumのこす

* fix

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
2023-02-23 20:46:14 +09:00
syuilo
c645f9f99f chore(dev): remove outdated tip 2023-02-23 20:36:03 +09:00
tamaina
a5341cbd7d CONTRIBUTING: enumの削除は気をつける 2023-02-23 11:33:49 +00:00
syuilo
3dd363a6c5 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-02-23 20:26:36 +09:00
syuilo
e630803922 enumの変更はしない 2023-02-23 20:26:33 +09:00
tamaina
cb3b167d61 Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop 2023-02-23 10:56:10 +00:00
tamaina
774b7fed1f update CHANGELOG.md 2023-02-23 10:55:54 +00:00
syuilo
cbf526b043 chore(client): tweak online users widget 2023-02-23 19:51:10 +09:00
syuilo
48331bc851 chore(client): tweak deck experience 2023-02-23 19:49:24 +09:00
tamaina
bda3d69539 fix(client):「キャッシュを削除」した後、ローカルのカスタム絵文字が表示されなくなる問題を修正
Fix #10044
2023-02-23 10:29:20 +00:00
syuilo
71900e0231 Release: 13.7.2 (#10035)
* ci: swcにしたためtypecheckは別途実施

* 🎨

* Update package.json

* マイグレーションが失敗することがあるのを修正

* refactor ci

* use tsc for build

Windowsだとエラーが出るため

* feat: swc build in windows (#10032)

* feat: add optional swc

* fix: windowsで動かない現象を修正

* fix: fix swc path alias

* fix: docker build時に`Host key verification failed`と言われてgitリポジトリからパッケージをインストールできないのでssh -> htpsに変更

* use swc

* chore(client): tweak custom emoji size

* enhance: make pwa icon maskable (#10033)

* 🎨

* feat(server): add @swc/core-android-arm64 to optional (#10034)

* feat: add optional swc

* fix: windowsで動かない現象を修正

* fix: fix swc path alias

* fix: docker build時に`Host key verification failed`と言われてgitリポジトリからパッケージをインストールできないのでssh -> htpsに変更

* feat(server): add @swc/core-android-arm64 to optional

* fix: conflict

* Update package.json

* chore(backend): fix indent

* Update CHANGELOG.md

* compress png

---------

Co-authored-by: CaffeinePower <86540016+cffnpwr@users.noreply.github.com>
Co-authored-by: Shogo Sensui <shogosensui@gmail.com>
Co-authored-by: tamaina <tamaina@hotmail.co.jp>
2023-02-23 17:36:36 +09:00
syuilo
694f08c79b compress png 2023-02-23 17:34:29 +09:00
syuilo
c328584bb6 Update CHANGELOG.md 2023-02-23 17:30:01 +09:00
tamaina
4c01198811 chore(backend): fix indent 2023-02-23 08:15:54 +00:00
syuilo
7781497b42 Update package.json 2023-02-23 16:42:36 +09:00
CaffeinePower
cde0eb621d feat(server): add @swc/core-android-arm64 to optional (#10034)
* feat: add optional swc

* fix: windowsで動かない現象を修正

* fix: fix swc path alias

* fix: docker build時に`Host key verification failed`と言われてgitリポジトリからパッケージをインストールできないのでssh -> htpsに変更

* feat(server): add @swc/core-android-arm64 to optional

* fix: conflict
2023-02-23 16:23:16 +09:00
syuilo
474b8789a7 🎨 2023-02-23 16:03:50 +09:00
Shogo Sensui
2189acdde1 enhance: make pwa icon maskable (#10033) 2023-02-23 15:59:21 +09:00
syuilo
c174f23389 chore(client): tweak custom emoji size 2023-02-23 15:42:57 +09:00
syuilo
4e23500732 use swc 2023-02-23 15:36:47 +09:00
CaffeinePower
b965f5e4a9 feat: swc build in windows (#10032)
* feat: add optional swc

* fix: windowsで動かない現象を修正

* fix: fix swc path alias

* fix: docker build時に`Host key verification failed`と言われてgitリポジトリからパッケージをインストールできないのでssh -> htpsに変更
2023-02-23 15:36:17 +09:00
syuilo
d1a69abf81 use tsc for build
Windowsだとエラーが出るため
2023-02-23 11:06:23 +09:00
syuilo
d2ef0efbff refactor ci 2023-02-23 10:56:01 +09:00
syuilo
ce5c78d0d2 マイグレーションが失敗することがあるのを修正 2023-02-23 10:40:15 +09:00
syuilo
28bea88da0 Update package.json 2023-02-23 10:17:00 +09:00
syuilo
a2e6f459e7 🎨 2023-02-23 08:29:16 +09:00
syuilo
0026c45fe0 ci: swcにしたためtypecheckは別途実施 2023-02-23 08:23:55 +09:00
syuilo
424292f335 Merge branch 'develop' 2023-02-23 08:09:32 +09:00
syuilo
8ca2f24df6 13.7.1 2023-02-23 08:09:22 +09:00
syuilo
fb7e5a3fac enhance(client): tweak renote collapsing logic 2023-02-23 08:08:17 +09:00
nenohi
5dd24e44d1 マイグレーションファイルの変更ミス (#10029) 2023-02-23 07:52:01 +09:00
tamaina
f7c6ea93d7 perf(backend): Use swc on pnpm build (#10026)
* perf(backend): Use swc on pnpm build

* update CHANGELOG

* no jest
2023-02-22 23:09:24 +09:00
31 changed files with 360 additions and 266 deletions

View File

@@ -36,8 +36,6 @@ jobs:
- backend
- frontend
- sw
lint:
- eslint
steps:
- uses: actions/checkout@v3.3.0
with:
@@ -53,4 +51,29 @@ jobs:
cache: 'pnpm'
- run: corepack enable
- run: pnpm i --frozen-lockfile
- run: pnpm --filter ${{ matrix.workspace }} run ${{ matrix.lint }}
- run: pnpm --filter ${{ matrix.workspace }} run eslint
typecheck:
needs: [pnpm_install]
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
workspace:
- backend
steps:
- uses: actions/checkout@v3.3.0
with:
fetch-depth: 0
submodules: true
- uses: pnpm/action-setup@v2
with:
version: 7
run_install: false
- uses: actions/setup-node@v3.6.0
with:
node-version: 18.x
cache: 'pnpm'
- run: corepack enable
- run: pnpm i --frozen-lockfile
- run: pnpm --filter ${{ matrix.workspace }} run typecheck

View File

@@ -8,6 +8,39 @@
You should also include the user name that made the change.
-->
## 13.7.3 (2023/02/23)
### Note
13.7.0以前から直接このバージョンにアップデートする場合は全ての通知が削除**されません。**
### Improvements
### Bugfixes
- Client: 「キャッシュを削除」した後、ローカルのカスタム絵文字が表示されなくなるされなくなる問題を修正
- Client: 通知設定画面で以前からグループの招待を有効化していた場合、通知の表示に失敗する問題の修正
- Client: 通知設定画面に古いトグルが残っていた問題を修正
## 13.7.2 (2023/02/23)
### Note
13.7.0以前からアップデートする場合は全ての通知が削除されます。
### Improvements
- enhance: make pwa icon maskable
- chore(client): tweak custom emoji size
### Bugfixes
- マイグレーションが失敗することがあるのを修正
## 13.7.1 (2023/02/23)
### Improvements
- pnpm buildではswcを使うように
### Bugfixes
- NODE_ENV=productionでビルドできないのを修正
## 13.7.0 (2023/02/22)
### Changes

View File

@@ -83,7 +83,7 @@ An actual domain will be assigned so you can test the federation.
- The title must be in the format `Release: x.y.z`.
- `x.y.z` is the new version you are trying to release.
3. Deploy and perform a simple QA check. Also verify that the tests passed.
4. Merge it.
4. Merge it. (Do not squash commit)
5. Create a [release of GitHub](https://github.com/misskey-dev/misskey/releases)
- The target branch must be `master`
- The tag name must be the version
@@ -278,9 +278,10 @@ SQLでは配列のインデックスは**1始まり**。
### null IN
nullが含まれる可能性のあるカラムにINするときは、そのままだとおかしくなるのでORなどでnullのハンドリングをしよう。
### `undefined`にご用心
MongoDBの時とは違い、findOneでレコードを取得する時に対象レコードが存在しない場合 **`undefined`** が返ってくるので注意。
MongoDBは`null`で返してきてたので、その感覚で`if (x === null)`とか書くとバグる。代わりに`if (x == null)`と書いてください
### enumの削除は気をつける
enumの列挙の内容の削除は、その値をもつレコードを全て削除しないといけない
削除が重たかったり不可能だったりする場合は、削除しないでおく
### Migration作成方法
packages/backendで:

View File

@@ -1846,6 +1846,7 @@ _notification:
pollEnded: "アンケートが終了"
receiveFollowRequest: "フォロー申請を受け取った"
followRequestAccepted: "フォローが受理された"
achievementEarned: "実績の獲得"
app: "連携アプリからの通知"
_actions:

View File

@@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "13.7.0",
"version": "13.7.3",
"codename": "nasubi",
"repository": {
"type": "git",

View File

@@ -1,25 +1,23 @@
{
"$schema": "https://json.schemastore.org/swcrc",
"jsc": {
"parser": {
"syntax": "typescript",
"dynamicImport": true,
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"$schema": "https://json.schemastore.org/swcrc",
"jsc": {
"parser": {
"syntax": "typescript",
"dynamicImport": true,
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"experimental": {
"keepImportAssertions": true
},
"baseUrl": ".",
"baseUrl": "src",
"paths": {
"@/*": [
"./src/*"
]
"@/*": ["*"]
},
"target": "es2021"
},
"minify": false
},
"minify": false
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 162 KiB

View File

@@ -2,6 +2,7 @@ export class dropGroup1676434944993 {
name = 'dropGroup1676434944993'
async up(queryRunner) {
await queryRunner.query(`TRUNCATE TABLE "notification"`, undefined);
await queryRunner.query(`ALTER TABLE "antenna" DROP CONSTRAINT "FK_ccbf5a8c0be4511133dcc50ddeb"`);
await queryRunner.query(`ALTER TABLE "notification" DROP CONSTRAINT "FK_8fe87814e978053a53b1beb7e98"`);
await queryRunner.query(`ALTER TABLE "antenna" DROP COLUMN "userGroupJoiningId"`);
@@ -10,19 +11,11 @@ export class dropGroup1676434944993 {
await queryRunner.query(`CREATE TYPE "public"."antenna_src_enum" AS ENUM('home', 'all', 'users', 'list')`);
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "public"."antenna_src_enum" USING "src"::"text"::"public"."antenna_src_enum"`);
await queryRunner.query(`DROP TYPE "public"."antenna_src_enum_old"`);
await queryRunner.query(`ALTER TYPE "public"."notification_type_enum" RENAME TO "notification_type_enum_old"`);
await queryRunner.query(`CREATE TYPE "public"."notification_type_enum" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app')`);
await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "public"."notification_type_enum" USING "type"::"text"::"public"."notification_type_enum"`);
await queryRunner.query(`DROP TYPE "public"."notification_type_enum_old"`);
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "emailNotificationTypes" SET DEFAULT '["follow","receiveFollowRequest"]'`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "user_profile" ALTER COLUMN "emailNotificationTypes" SET DEFAULT '["follow", "receiveFollowRequest", "groupInvited"]'`);
await queryRunner.query(`CREATE TYPE "public"."notification_type_enum_old" AS ENUM('follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'groupInvited', 'achievementEarned', 'app')`);
await queryRunner.query(`ALTER TABLE "notification" ALTER COLUMN "type" TYPE "public"."notification_type_enum_old" USING "type"::"text"::"public"."notification_type_enum_old"`);
await queryRunner.query(`DROP TYPE "public"."notification_type_enum"`);
await queryRunner.query(`ALTER TYPE "public"."notification_type_enum_old" RENAME TO "notification_type_enum"`);
await queryRunner.query(`CREATE TYPE "public"."antenna_src_enum_old" AS ENUM('home', 'all', 'users', 'list', 'group')`);
await queryRunner.query(`ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "public"."antenna_src_enum_old" USING "src"::"text"::"public"."antenna_src_enum_old"`);
await queryRunner.query(`DROP TYPE "public"."antenna_src_enum"`);

View File

@@ -4,6 +4,6 @@ export class ad1676438468213 {
await queryRunner.query(`ALTER TABLE "ad" ADD "startsAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "startsAt"`);
await queryRunner.query(`ALTER TABLE "ad" DROP COLUMN "startsAt"`);
}
}

View File

@@ -7,9 +7,9 @@
"start": "node ./built/index.js",
"start:test": "NODE_ENV=test node ./built/index.js",
"migrate": "pnpm typeorm migration:run -d ormconfig.js",
"build:swc": "swc src -d built -D",
"build": "swc src -d built -D",
"watch:swc": "swc src -d built -D -w",
"build": "tsc -p tsconfig.json || echo done. && tsc-alias -p tsconfig.json",
"build:tsc": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
"watch": "node watch.mjs",
"typecheck": "tsc --noEmit",
"eslint": "eslint --quiet \"src/**/*.ts\"",
@@ -21,6 +21,17 @@
"test-and-coverage": "pnpm jest-and-coverage"
},
"optionalDependencies": {
"@swc/core-android-arm64": "^1.3.11",
"@swc/core-darwin-arm64": "^1.3.36",
"@swc/core-darwin-x64": "^1.3.36",
"@swc/core-linux-arm-gnueabihf": "^1.3.36",
"@swc/core-linux-arm64-gnu": "^1.3.36",
"@swc/core-linux-arm64-musl": "^1.3.36",
"@swc/core-linux-x64-gnu": "^1.3.36",
"@swc/core-linux-x64-musl": "^1.3.36",
"@swc/core-win32-arm64-msvc": "^1.3.36",
"@swc/core-win32-ia32-msvc": "^1.3.36",
"@swc/core-win32-x64-msvc": "^1.3.36",
"@tensorflow/tfjs": "4.2.0",
"@tensorflow/tfjs-node": "4.2.0"
},
@@ -41,6 +52,8 @@
"@nestjs/testing": "9.3.9",
"@peertube/http-signature": "1.7.0",
"@sinonjs/fake-timers": "10.0.2",
"@swc/cli": "0.1.62",
"@swc/core": "1.3.35",
"accepts": "1.3.8",
"ajv": "8.12.0",
"archiver": "5.3.1",
@@ -133,8 +146,6 @@
"devDependencies": {
"@jest/globals": "29.4.3",
"@redocly/openapi-core": "1.0.0-beta.123",
"@swc/cli": "0.1.62",
"@swc/core": "1.3.35",
"@swc/jest": "0.2.24",
"@types/accepts": "1.3.5",
"@types/archiver": "5.3.1",
@@ -185,4 +196,4 @@
"jest": "29.4.3",
"jest-mock": "29.4.3"
}
}
}

View File

@@ -94,13 +94,6 @@ export class NotificationEntityService implements OnModuleInit {
}),
reaction: notification.reaction,
} : {}),
...(notification.type === 'pollVote' ? { // TODO: そのうち消す
note: this.noteEntityService.pack(notification.note ?? notification.noteId!, { id: notification.notifieeId }, {
detail: true,
_hint_: options._hintForEachNotes_,
}),
choice: notification.choice,
} : {}),
...(notification.type === 'pollEnded' ? {
note: this.noteEntityService.pack(notification.note ?? notification.noteId!, { id: notification.notifieeId }, {
detail: true,

View File

@@ -1,5 +1,5 @@
import { Entity, Index, JoinColumn, ManyToOne, Column, PrimaryColumn } from 'typeorm';
import { notificationTypes } from '@/types.js';
import { notificationTypes, obsoleteNotificationTypes } from '@/types.js';
import { id } from '../id.js';
import { User } from './User.js';
import { Note } from './Note.js';
@@ -58,7 +58,6 @@ export class Notification {
* renote - 投稿がRenoteされた
* quote - 投稿が引用Renoteされた
* reaction - 投稿にリアクションされた
* pollVote - 投稿のアンケートに投票された (廃止)
* pollEnded - 自分のアンケートもしくは自分が投票したアンケートが終了した
* receiveFollowRequest - フォローリクエストされた
* followRequestAccepted - 自分の送ったフォローリクエストが承認された
@@ -67,7 +66,10 @@ export class Notification {
*/
@Index()
@Column('enum', {
enum: notificationTypes,
enum: [
...notificationTypes,
...obsoleteNotificationTypes,
],
comment: 'The type of the Notification.',
})
public type: typeof notificationTypes[number];

View File

@@ -1,5 +1,5 @@
import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
import { ffVisibility, notificationTypes } from '@/types.js';
import { obsoleteNotificationTypes, ffVisibility, notificationTypes } from '@/types.js';
import { id } from '../id.js';
import { User } from './User.js';
import { Page } from './Page.js';
@@ -205,7 +205,7 @@ export class UserProfile {
enum: [
...notificationTypes,
// マイグレーションで削除が困難なので古いenumは残しておく
'groupInvited',
...obsoleteNotificationTypes,
],
array: true,
default: [],

View File

@@ -1,7 +1,7 @@
import { Brackets } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common';
import type { UsersRepository, FollowingsRepository, MutingsRepository, UserProfilesRepository, NotificationsRepository } from '@/models/index.js';
import { notificationTypes } from '@/types.js';
import { obsoleteNotificationTypes, notificationTypes } from '@/types.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { QueryService } from '@/core/QueryService.js';
import { NoteReadService } from '@/core/NoteReadService.js';
@@ -41,11 +41,12 @@ export const paramDef = {
following: { type: 'boolean', default: false },
unreadOnly: { type: 'boolean', default: false },
markAsRead: { type: 'boolean', default: true },
// 後方互換のため、廃止された通知タイプも受け付ける
includeTypes: { type: 'array', items: {
type: 'string', enum: notificationTypes,
type: 'string', enum: [...notificationTypes, ...obsoleteNotificationTypes],
} },
excludeTypes: { type: 'array', items: {
type: 'string', enum: notificationTypes,
type: 'string', enum: [...notificationTypes, ...obsoleteNotificationTypes],
} },
},
required: [],
@@ -84,6 +85,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (notificationTypes.every(type => ps.excludeTypes?.includes(type))) {
return [];
}
const includeTypes = ps.includeTypes && ps.includeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
const excludeTypes = ps.excludeTypes && ps.excludeTypes.filter(type => !(obsoleteNotificationTypes).includes(type as any)) as typeof notificationTypes[number][];
const followingQuery = this.followingsRepository.createQueryBuilder('following')
.select('following.followeeId')
.where('following.followerId = :followerId', { followerId: me.id });
@@ -143,10 +148,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
query.setParameters(followingQuery.getParameters());
}
if (ps.includeTypes && ps.includeTypes.length > 0) {
query.andWhere('notification.type IN (:...includeTypes)', { includeTypes: ps.includeTypes });
} else if (ps.excludeTypes && ps.excludeTypes.length > 0) {
query.andWhere('notification.type NOT IN (:...excludeTypes)', { excludeTypes: ps.excludeTypes });
if (includeTypes && includeTypes.length > 0) {
query.andWhere('notification.type IN (:...includeTypes)', { includeTypes });
} else if (excludeTypes && excludeTypes.length > 0) {
query.andWhere('notification.type NOT IN (:...excludeTypes)', { excludeTypes });
}
if (ps.unreadOnly) {

View File

@@ -9,12 +9,14 @@
{
"src": "/static-assets/icons/192.png",
"sizes": "192x192",
"type": "image/png"
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/static-assets/icons/512.png",
"sizes": "512x512",
"type": "image/png"
"type": "image/png",
"purpose": "maskable"
}
],
"share_target": {

View File

@@ -1,4 +1,5 @@
export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollVote', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] as const;
export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] as const;
export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const;
export const noteVisibilities = ['public', 'home', 'followers', 'specified'] as const;

View File

@@ -21,7 +21,7 @@
"autosize": "5.0.2",
"blurhash": "2.0.5",
"broadcast-channel": "4.20.2",
"browser-image-resizer": "git+https://github.com/misskey-dev/browser-image-resizer#v2.2.1-misskey.3",
"browser-image-resizer": "github:misskey-dev/browser-image-resizer#v2.2.1-misskey.3",
"canvas-confetti": "1.6.0",
"chart.js": "4.2.1",
"chartjs-adapter-date-fns": "3.0.0",
@@ -63,9 +63,9 @@
"typescript": "4.9.5",
"uuid": "9.0.0",
"vanilla-tilt": "1.8.0",
"vue-plyr": "7.0.0",
"vite": "4.1.2",
"vue": "3.2.47",
"vue-plyr": "7.0.0",
"vue-prism-editor": "2.0.0-alpha.2",
"vuedraggable": "next"
},
@@ -96,4 +96,4 @@
"vue-eslint-parser": "9.1.0",
"vue-tsc": "1.1.4"
}
}
}

View File

@@ -155,7 +155,6 @@ import { deepClone } from '@/scripts/clone';
import { useTooltip } from '@/scripts/use-tooltip';
import { claimAchievement } from '@/scripts/achievements';
import { getNoteSummary } from '@/scripts/get-note-summary';
import { shownNoteIds } from '@/os';
import { MenuItem } from '@/types/menu';
const props = defineProps<{
@@ -209,9 +208,7 @@ const translation = ref<any>(null);
const translating = ref(false);
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.user.instance);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.visibility) || appearNote.userId === $i.id);
let renoteCollapsed = $ref(defaultStore.state.collapseRenotes && isRenote && (($i && ($i.id === note.userId)) || shownNoteIds.has(appearNote.id)));
shownNoteIds.add(appearNote.id);
let renoteCollapsed = $ref(defaultStore.state.collapseRenotes && isRenote && (($i && ($i.id === note.userId)) || (appearNote.myReaction != null)));
const keymap = {
'r': () => reply(true),

View File

@@ -6,7 +6,7 @@
:with-ok-button="true"
:ok-button-disabled="false"
@ok="ok()"
@close="dialog.close()"
@close="dialog?.close()"
@closed="emit('closed')"
>
<template #header>{{ i18n.ts.notificationSetting }}</template>
@@ -25,7 +25,7 @@
<MkButton inline @click="disableAll">{{ i18n.ts.disableAll }}</MkButton>
<MkButton inline @click="enableAll">{{ i18n.ts.enableAll }}</MkButton>
</div>
<MkSwitch v-for="ntype in notificationTypes" :key="ntype" v-model="typesMap[ntype]">{{ i18n.t(`_notification._types.${ntype}`) }}</MkSwitch>
<MkSwitch v-for="ntype in notificationTypes" :key="ntype" v-model="typesMap[ntype].value">{{ i18n.t(`_notification._types.${ntype}`) }}</MkSwitch>
</template>
</div>
</MkSpacer>
@@ -33,14 +33,16 @@
</template>
<script lang="ts" setup>
import { } from 'vue';
import { notificationTypes } from 'misskey-js';
import { ref, Ref } from 'vue';
import MkSwitch from './MkSwitch.vue';
import MkInfo from './MkInfo.vue';
import MkButton from './MkButton.vue';
import MkModalWindow from '@/components/MkModalWindow.vue';
import { notificationTypes } from '@/const';
import { i18n } from '@/i18n';
type TypesMap = Record<typeof notificationTypes[number], Ref<boolean>>
const emit = defineEmits<{
(ev: 'done', v: { includingTypes: string[] | null }): void,
(ev: 'closed'): void,
@@ -54,39 +56,35 @@ const props = withDefaults(defineProps<{
showGlobalToggle: true,
});
let includingTypes = $computed(() => props.includingTypes ?? []);
let includingTypes = $computed(() => props.includingTypes?.filter(x => notificationTypes.includes(x)) ?? []);
const dialog = $shallowRef<InstanceType<typeof MkModalWindow>>();
let typesMap = $ref<Record<typeof notificationTypes[number], boolean>>({});
const typesMap: TypesMap = notificationTypes.reduce((p, t) => ({ ...p, [t]: ref<boolean>(includingTypes.includes(t)) }), {} as any);
let useGlobalSetting = $ref((includingTypes === null || includingTypes.length === 0) && props.showGlobalToggle);
for (const ntype of notificationTypes) {
typesMap[ntype] = includingTypes.includes(ntype);
}
function ok() {
if (useGlobalSetting) {
emit('done', { includingTypes: null });
} else {
emit('done', {
includingTypes: (Object.keys(typesMap) as typeof notificationTypes[number][])
.filter(type => typesMap[type]),
.filter(type => typesMap[type].value),
});
}
dialog.close();
if (dialog) dialog.close();
}
function disableAll() {
for (const type in typesMap) {
typesMap[type as typeof notificationTypes[number]] = false;
for (const type of notificationTypes) {
typesMap[type].value = false;
}
}
function enableAll() {
for (const type in typesMap) {
typesMap[type as typeof notificationTypes[number]] = true;
for (const type of notificationTypes) {
typesMap[type].value = true;
}
}
</script>

View File

@@ -18,7 +18,6 @@
<script lang="ts" setup>
import { onUnmounted, onMounted, computed, shallowRef } from 'vue';
import { notificationTypes } from 'misskey-js';
import MkPagination, { Paging } from '@/components/MkPagination.vue';
import XNotification from '@/components/MkNotification.vue';
import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
@@ -26,6 +25,7 @@ import XNote from '@/components/MkNote.vue';
import { stream } from '@/stream';
import { $i } from '@/account';
import { i18n } from '@/i18n';
import { notificationTypes } from '@/const';
const props = defineProps<{
includeTypes?: typeof notificationTypes[number][];

View File

@@ -41,7 +41,7 @@ let errored = $ref(url.value == null);
<style lang="scss" module>
.root {
height: 2.5em;
height: 2em;
vertical-align: middle;
transition: transform 0.2s ease;

View File

@@ -43,3 +43,6 @@ https://github.com/sindresorhus/file-type/blob/main/supported.js
https://github.com/sindresorhus/file-type/blob/main/core.js
https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers
*/
export const notificationTypes = ['follow', 'mention', 'reply', 'renote', 'quote', 'reaction', 'pollEnded', 'receiveFollowRequest', 'followRequestAccepted', 'achievementEarned', 'app'] as const;
export const obsoleteNotificationTypes = ['pollVote', 'groupInvited'] as const;

View File

@@ -603,9 +603,3 @@ export function checkExistence(fileData: ArrayBuffer): Promise<any> {
});
});
}*/
export const shownNoteIds = new Set();
window.setInterval(() => {
shownNoteIds.clear();
}, 1000 * 60 * 5);

View File

@@ -136,6 +136,7 @@ definePageMetadata(computed(() => ({
.user {
flex: 1;
min-width: 0;
}
.unassign {

View File

@@ -17,12 +17,12 @@
<script lang="ts" setup>
import { computed } from 'vue';
import { notificationTypes } from 'misskey-js';
import XNotifications from '@/components/MkNotifications.vue';
import MkNotes from '@/components/MkNotes.vue';
import * as os from '@/os';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
import { notificationTypes } from '@/const';
let tab = $ref('all');
let includeTypes = $ref<string[] | null>(null);

View File

@@ -181,7 +181,7 @@ const menuDef = computed(() => [{
miLocalStorage.removeItem('theme');
miLocalStorage.removeItem('emojis');
miLocalStorage.removeItem('lastEmojisFetchedAt');
await fetchCustomEmojis();
await fetchCustomEmojis(true);
unisonReload();
},
}, {

View File

@@ -27,7 +27,6 @@
<script lang="ts" setup>
import { defineAsyncComponent } from 'vue';
import { notificationTypes } from 'misskey-js';
import FormLink from '@/components/form/link.vue';
import FormSection from '@/components/form/section.vue';
import MkSwitch from '@/components/MkSwitch.vue';
@@ -36,6 +35,7 @@ import { $i } from '@/account';
import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
import MkPushNotificationAllowButton from '@/components/MkPushNotificationAllowButton.vue';
import { notificationTypes } from '@/const';
let allowButton = $shallowRef<InstanceType<typeof MkPushNotificationAllowButton>>();
let pushRegistrationInServer = $computed(() => allowButton?.pushRegistrationInServer);

View File

@@ -98,6 +98,7 @@ import { $i } from '@/account';
import { i18n } from '@/i18n';
import { mainRouter } from '@/router';
import { unisonReload } from '@/scripts/unison-reload';
import { deviceKind } from '@/scripts/device-kind';
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
mainRouter.navHook = (path, flag): boolean => {
@@ -115,7 +116,7 @@ window.addEventListener('resize', () => {
isMobile.value = window.innerWidth <= 500;
});
const snapScroll = isMobile;
const snapScroll = deviceKind === 'smartphone' || deviceKind === 'tablet';
const drawerMenuShowing = ref(false);
const route = 'TODO';

View File

@@ -1,7 +1,7 @@
<template>
<div class="mkw-onlineUsers data-cy-mkw-onlineUsers" :class="{ _panel: !widgetProps.transparent, pad: !widgetProps.transparent }">
<I18n v-if="onlineUsersCount" :src="i18n.ts.onlineUsersCount" text-tag="span" class="text">
<template #n><b>{{ onlineUsersCount }}</b></template>
<template #n><b>{{ number(onlineUsersCount) }}</b></template>
</I18n>
</div>
</template>
@@ -13,6 +13,7 @@ import { GetFormResultType } from '@/scripts/form';
import * as os from '@/os';
import { useInterval } from '@/scripts/use-interval';
import { i18n } from '@/i18n';
import number from '@/filters/number';
const name = 'onlineUsers';

374
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff