Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
yupix committed Nov 30, 2023
2 parents 895cf1d + ca424df commit 4f44397
Show file tree
Hide file tree
Showing 47 changed files with 494 additions and 133 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/get-api-diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,13 @@ jobs:
api-json-name: [api-base.json, api-head.json]
include:
- api-json-name: api-base.json
repo-name: ${{ github.event.pull_request.base.repo.full_name }}
ref: ${{ github.base_ref }}
- api-json-name: api-head.json
repo-name: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.head_ref }}
ref: refs/pull/${{ github.event.number }}/merge

steps:
- uses: actions/[email protected]
with:
repository: ${{ matrix.repo-name }}
ref: ${{ matrix.ref }}
submodules: true
- name: Install pnpm
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@
- Fix: MFM `$[unixtime ]` に不正な値を入力した際に発生する各種エラーを修正

### Client
- Feat: 今日誕生日のフォロー中のユーザーを一覧表示できるウィジェットを追加
- Enhance: 絵文字のオートコンプリート機能強化 #12364
- Enhance: ユーザーのRawデータを表示するページが復活
- Enhance: リアクション選択時に音を鳴らせるように
- Enhance: サウンドにドライブのファイルを使用できるように
- Enhance: ナビゲーションバーに項目「キャッシュを削除」を追加
- Enhance: Shareページで投稿を完了すると、親ウィンドウ(親フレーム)にpostMessageするように
- Enhance: チャンネル、クリップ、ページ、Play、ギャラリーにURLのコピーボタンを設置 #11305
- Enhance: ノートプレビューに「内容を隠す」が反映されるように
- fix: 「設定のバックアップ」で一部の項目がバックアップに含まれていなかった問題を修正
- Fix: ウィジェットのジョブキューにて音声の発音方法変更に追従できていなかったのを修正 #12367
- Enhance: 絵文字の詳細ページに記載される情報を追加
- Fix: コードエディタが正しく表示されない問題を修正
- Fix: プロフィールの「ファイル」にセンシティブな画像がある際のデザインを修正
- Fix: 一度に大量の通知が入った際に通知音が音割れする問題を修正
- Fix: 共有機能をサポートしていないブラウザの場合は共有ボタンを非表示にする #11305
- Fix: 通知のグルーピング設定を変更してもリロードされるまで表示が変わらない問題を修正 #12470

### Server
- Enhance: MFM `$[ruby ]` が他ソフトウェアと連合されるように
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ RUN apt-get update \
&& corepack enable \
&& groupadd -g "${GID}" misskey \
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
&& find / -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
&& find / -type d -path /proc -prune -o -type f -perm /g+s -ignore_readdir_race -exec chmod g-s {} \; \
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /g+s -ignore_readdir_race -exec chmod g-s {} \; \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists

Expand Down
12 changes: 12 additions & 0 deletions locales/generateDTS.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ export default function generateDTS() {
ts.NodeFlags.Const | ts.NodeFlags.Ambient | ts.NodeFlags.ContextFlags,
),
),
ts.factory.createFunctionDeclaration(
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
undefined,
ts.factory.createIdentifier('build'),
undefined,
[],
ts.factory.createTypeReferenceNode(
ts.factory.createIdentifier('Locale'),
undefined,
),
undefined,
),
ts.factory.createExportDefault(ts.factory.createIdentifier('locales')),
];
const printed = ts.createPrinter({
Expand Down
4 changes: 4 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,8 @@ export interface Locale {
"sensitiveWords": string;
"sensitiveWordsDescription": string;
"sensitiveWordsDescription2": string;
"hiddenTags": string;
"hiddenTagsDescription": string;
"notesSearchNotAvailable": string;
"license": string;
"unfavoriteConfirm": string;
Expand Down Expand Up @@ -2108,6 +2110,7 @@ export interface Locale {
"chooseList": string;
};
"clicker": string;
"birthdayFollowings": string;
};
"_cw": {
"hide": string;
Expand Down Expand Up @@ -2503,4 +2506,5 @@ export interface Locale {
declare const locales: {
[lang: string]: Locale;
};
export function build(): Locale;
export default locales;
58 changes: 31 additions & 27 deletions locales/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,37 @@ const primaries = {
// 何故か文字列にバックスペース文字が混入することがあり、YAMLが壊れるので取り除く
const clean = (text) => text.replace(new RegExp(String.fromCodePoint(0x08), 'g'), '');

const locales = languages.reduce((a, c) => (a[c] = yaml.load(clean(fs.readFileSync(new URL(`${c}.yml`, import.meta.url), 'utf-8'))) || {}, a), {});
export function build() {
const locales = languages.reduce((a, c) => (a[c] = yaml.load(clean(fs.readFileSync(new URL(`${c}.yml`, import.meta.url), 'utf-8'))) || {}, a), {});

// 空文字列が入ることがあり、フォールバックが動作しなくなるのでプロパティごと消す
const removeEmpty = (obj) => {
for (const [k, v] of Object.entries(obj)) {
if (v === '') {
delete obj[k];
} else if (typeof v === 'object') {
removeEmpty(v);
// 空文字列が入ることがあり、フォールバックが動作しなくなるのでプロパティごと消す
const removeEmpty = (obj) => {
for (const [k, v] of Object.entries(obj)) {
if (v === '') {
delete obj[k];
} else if (typeof v === 'object') {
removeEmpty(v);
}
}
}
return obj;
};
removeEmpty(locales);
return obj;
};
removeEmpty(locales);

export default Object.entries(locales)
.reduce((a, [k ,v]) => (a[k] = (() => {
const [lang] = k.split('-');
switch (k) {
case 'ja-JP': return v;
case 'ja-KS':
case 'en-US': return merge(locales['ja-JP'], v);
default: return merge(
locales['ja-JP'],
locales['en-US'],
locales[`${lang}-${primaries[lang]}`] ?? {},
v
);
}
})(), a), {});
return Object.entries(locales)
.reduce((a, [k, v]) => (a[k] = (() => {
const [lang] = k.split('-');
switch (k) {
case 'ja-JP': return v;
case 'ja-KS':
case 'en-US': return merge(locales['ja-JP'], v);
default: return merge(
locales['ja-JP'],
locales['en-US'],
locales[`${lang}-${primaries[lang]}`] ?? {},
v
);
}
})(), a), {});
}

export default build();
3 changes: 3 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,8 @@ resetPasswordConfirm: "パスワードリセットしますか?"
sensitiveWords: "センシティブワード"
sensitiveWordsDescription: "設定したワードが含まれるノートの公開範囲をホームにします。改行で区切って複数設定できます。"
sensitiveWordsDescription2: "スペースで区切るとAND指定になり、キーワードをスラッシュで囲むと正規表現になります。"
hiddenTags: "非表示ハッシュタグ"
hiddenTagsDescription: "設定したタグをトレンドに表示させないようにします。改行で区切って複数設定できます。"
notesSearchNotAvailable: "ノート検索は利用できません。"
license: "ライセンス"
unfavoriteConfirm: "お気に入り解除しますか?"
Expand Down Expand Up @@ -2014,6 +2016,7 @@ _widgets:
_userList:
chooseList: "リストを選択"
clicker: "クリッカー"
birthdayFollowings: "今日誕生日のユーザー"

_cw:
hide: "隠す"
Expand Down
16 changes: 16 additions & 0 deletions packages/backend/migration/1700902349231-add-bday-index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class AddBdayIndex1700902349231 {
name = 'AddBdayIndex1700902349231'

async up(queryRunner) {
await queryRunner.query(`CREATE INDEX "IDX_de22cd2b445eee31ae51cdbe99" ON "user_profile" (SUBSTR("birthday", 6, 5))`);
}

async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_de22cd2b445eee31ae51cdbe99"`);
}
}
1 change: 1 addition & 0 deletions packages/backend/src/models/UserProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class MiUserProfile {
})
public location: string | null;

@Index()
@Column('char', {
length: 10, nullable: true,
comment: 'The birthday (YYYY-MM-DD) of the User.',
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/models/json-schema/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ export const packedNoteSchema = {
optional: false, nullable: false,
},
},
clippedCount: {
type: 'number',
optional: true, nullable: false,
},

myReaction: {
type: 'object',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@ export const meta = {
items: {
type: 'object',
optional: false, nullable: false,
properties: {
code: {
type: 'string',
optional: false, nullable: false,
example: 'GR6S02ERUA5VR',
},
},
ref: 'InviteCode',
},
},
} as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const meta = {
items: {
type: 'object',
optional: false, nullable: false,
ref: 'InviteCode',
},
},
} as const;
Expand Down
8 changes: 1 addition & 7 deletions packages/backend/src/server/api/endpoints/invite/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,7 @@ export const meta = {
res: {
type: 'object',
optional: false, nullable: false,
properties: {
code: {
type: 'string',
optional: false, nullable: false,
example: 'GR6S02ERUA5VR',
},
},
ref: 'InviteCode',
},
} as const;

Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/server/api/endpoints/invite/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import type { RegistrationTicketsRepository } from '@/models/_.js';
import { InviteCodeEntityService } from '@/core/entities/InviteCodeEntityService.js';
import { QueryService } from '@/core/QueryService.js';
import { DI } from '@/di-symbols.js';
import { ApiError } from '../../error.js';

export const meta = {
tags: ['meta'],
Expand All @@ -23,6 +22,7 @@ export const meta = {
items: {
type: 'object',
optional: false, nullable: false,
ref: 'InviteCode',
},
},
} as const;
Expand Down
23 changes: 23 additions & 0 deletions packages/backend/src/server/api/endpoints/users/following.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export const meta = {
code: 'FORBIDDEN',
id: 'f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba',
},

birthdayInvalid: {
message: 'Birthday date format is invalid.',
code: 'BIRTHDAY_DATE_FORMAT_INVALID',
id: 'a2b007b9-4782-4eba-abd3-93b05ed4130d',
},
},
} as const;

Expand All @@ -59,6 +65,8 @@ export const paramDef = {
nullable: true,
description: 'The local host is represented with `null`.',
},

birthday: { type: 'string', nullable: true },
},
anyOf: [
{ required: ['userId'] },
Expand Down Expand Up @@ -117,6 +125,21 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
.andWhere('following.followerId = :userId', { userId: user.id })
.innerJoinAndSelect('following.followee', 'followee');

if (ps.birthday) {
try {
const d = new Date(ps.birthday);
d.setHours(0, 0, 0, 0);
const birthday = `${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}`;
const birthdayUserQuery = this.userProfilesRepository.createQueryBuilder('user_profile');
birthdayUserQuery.select('user_profile.userId')
.where(`SUBSTR(user_profile.birthday, 6, 5) = '${birthday}'`);

query.andWhere(`following.followeeId IN (${ birthdayUserQuery.getQuery() })`);
} catch (err) {
throw new ApiError(meta.errors.birthdayInvalid);
}
}

const followings = await query
.limit(ps.limit)
.getMany();
Expand Down
28 changes: 16 additions & 12 deletions packages/frontend/src/boot/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,20 +202,24 @@ export async function common(createVue: () => App<Element>) {
}
}, { immediate: true });

if (defaultStore.state.keepScreenOn) {
if ('wakeLock' in navigator) {
navigator.wakeLock.request('screen')
.then(() => {
document.addEventListener('visibilitychange', async () => {
if (document.visibilityState === 'visible') {
navigator.wakeLock.request('screen');
}
});
})
// Keep screen on
const onVisibilityChange = () => document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
navigator.wakeLock.request('screen');
}
});
if (defaultStore.state.keepScreenOn && 'wakeLock' in navigator) {
navigator.wakeLock.request('screen')
.then(onVisibilityChange)
.catch(() => {
// If Permission fails on an AppleDevice such as Safari
// On WebKit-based browsers, user activation is required to send wake lock request
// https://webkit.org/blog/13862/the-user-activation-api/
document.addEventListener(
'click',
() => navigator.wakeLock.request('screen').then(onVisibilityChange),
{ once: true },
);
});
}
}

//#region Fetch user
Expand Down
23 changes: 19 additions & 4 deletions packages/frontend/src/components/MkCwButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,22 @@ import MkButton from '@/components/MkButton.vue';
const props = defineProps<{
modelValue: boolean;
note: Misskey.entities.Note;
text: string | null;
files: Misskey.entities.DriveFile[];
poll?: {
expiresAt: string | null;
multiple: boolean;
choices: {
isVoted: boolean;
text: string;
votes: number;
}[];
} | {
choices: string[];
multiple: boolean;
expiresAt: string | null;
expiredAfter: string | null;
};
}>();
const emit = defineEmits<{
Expand All @@ -25,9 +40,9 @@ const emit = defineEmits<{
const label = computed(() => {
return concat([
props.note.text ? [i18n.t('_cw.chars', { count: props.note.text.length })] : [],
props.note.files && props.note.files.length !== 0 ? [i18n.t('_cw.files', { count: props.note.files.length })] : [],
props.note.poll != null ? [i18n.ts.poll] : [],
props.text ? [i18n.t('_cw.chars', { count: props.text.length })] : [],
props.files.length !== 0 ? [i18n.t('_cw.files', { count: props.files.length })] : [],
props.poll != null ? [i18n.ts.poll] : [],
] as string[][]).join(' / ');
});
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div style="container-type: inline-size;">
<p v-if="appearNote.cw != null" :class="$style.cw">
<Mfm v-if="appearNote.cw != ''" style="margin-right: 8px;" :text="appearNote.cw" :author="appearNote.user" :nyaize="'respect'"/>
<MkCwButton v-model="showContent" :note="appearNote" style="margin: 4px 0;"/>
<MkCwButton v-model="showContent" :text="appearNote.text" :files="appearNote.files" :poll="appearNote.poll" style="margin: 4px 0;"/>
</p>
<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]">
<div :class="$style.text">
Expand Down
Loading

0 comments on commit 4f44397

Please sign in to comment.