Skip to content

Commit

Permalink
Merge branch 'develop' into refactor-use-scroll-xy
Browse files Browse the repository at this point in the history
  • Loading branch information
kakkokari-gtyih authored Apr 1, 2024
2 parents 1b8fd9f + 61978cb commit cd220cb
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test-backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ jobs:
with:
version: 8
run_install: false
- name: Install FFmpeg
uses: FedericoCarboni/setup-ffmpeg@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/[email protected]
with:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- Enhance: 映像・音声の再生にブラウザのネイティブプレイヤーを使用できるように
- Enhance: 映像・音声の再生メニューに「再生速度」「ループ再生」「ピクチャインピクチャ」を追加
- Enhance: 映像・音声の再生にキーボードショートカットが使えるように
- Enhance: ノートについているリアクションの「もっと!」から、リアクションの一覧を表示できるように
- Fix: 一部のページ内リンクが正しく動作しない問題を修正
- Fix: 周年の実績が閏年を考慮しない問題を修正
- Fix: ローカルURLのプレビューポップアップが左上に表示される
Expand All @@ -40,6 +41,7 @@
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/440)
- Fix: エンドポイント`notes/translate`のエラーを改善
- Fix: CleanRemoteFilesProcessorService report progress from 100% (#13632)
- Fix: 一部の音声ファイルが映像ファイルとして扱われる問題を修正

## 2024.3.1

Expand Down
8 changes: 8 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8830,6 +8830,14 @@ export interface Locale extends ILocale {
* ボタン
*/
"button": string;
/**
* 動的ブロック
*/
"dynamic": string;
/**
* このブロックは廃止されています。今後は{play}を利用してください。
*/
"dynamicDescription": ParameterizedString<"play">;
/**
* ノート埋め込み
*/
Expand Down
3 changes: 2 additions & 1 deletion locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2331,6 +2331,8 @@ _pages:
section: "セクション"
image: "画像"
button: "ボタン"
dynamic: "動的ブロック"
dynamicDescription: "このブロックは廃止されています。今後は{play}を利用してください。"

note: "ノート埋め込み"
_note:
Expand Down Expand Up @@ -2625,4 +2627,3 @@ _mediaControls:
pip: "ピクチャインピクチャ"
playbackRate: "再生速度"
loop: "ループ再生"

49 changes: 48 additions & 1 deletion packages/backend/src/core/FileInfoService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import FFmpeg from 'fluent-ffmpeg';
import isSvg from 'is-svg';
import probeImageSize from 'probe-image-size';
import { type predictionType } from 'nsfwjs';
import sharp from 'sharp';
import { sharpBmp } from '@misskey-dev/sharp-read-bmp';
import { encode } from 'blurhash';
import { createTempDir } from '@/misc/create-temp.js';
import { AiService } from '@/core/AiService.js';
import { LoggerService } from '@/core/LoggerService.js';
import type Logger from '@/logger.js';
import { bindThis } from '@/decorators.js';

export type FileInfo = {
Expand Down Expand Up @@ -49,9 +50,13 @@ const TYPE_SVG = {

@Injectable()
export class FileInfoService {
private logger: Logger;

constructor(
private aiService: AiService,
private loggerService: LoggerService,
) {
this.logger = this.loggerService.getLogger('file-info');
}

/**
Expand Down Expand Up @@ -317,6 +322,34 @@ export class FileInfoService {
return mime;
}

/**
* ビデオファイルにビデオトラックがあるかどうかチェック
* (ない場合:m4a, webmなど)
*
* @param path ファイルパス
* @returns ビデオトラックがあるかどうか(エラー発生時は常に`true`を返す)
*/
@bindThis
private hasVideoTrackOnVideoFile(path: string): Promise<boolean> {
const sublogger = this.logger.createSubLogger('ffprobe');
sublogger.info(`Checking the video file. File path: ${path}`);
return new Promise((resolve) => {
try {
FFmpeg.ffprobe(path, (err, metadata) => {
if (err) {
sublogger.warn(`Could not check the video file. Returns true. File path: ${path}`, err);
resolve(true);
return;
}
resolve(metadata.streams.some((stream) => stream.codec_type === 'video'));
});
} catch (err) {
sublogger.warn(`Could not check the video file. Returns true. File path: ${path}`, err as Error);
resolve(true);
}
});
}

/**
* Detect MIME Type and extension
*/
Expand All @@ -339,6 +372,20 @@ export class FileInfoService {
return TYPE_SVG;
}

if ((type.mime.startsWith('video') || type.mime === 'application/ogg') && !(await this.hasVideoTrackOnVideoFile(path))) {
const newMime = `audio/${type.mime.split('/')[1]}`;
if (newMime === 'audio/mp4') {
return {
mime: 'audio/mp4',
ext: 'm4a',
};
}
return {
mime: newMime,
ext: type.ext,
};
}

return {
mime: this.fixMime(type.mime),
ext: type.ext,
Expand Down
Binary file added packages/backend/test/resources/kick_gaba7.m4a
Binary file not shown.
27 changes: 23 additions & 4 deletions packages/backend/test/unit/FileInfoService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { GlobalModule } from '@/GlobalModule.js';
import { FileInfoService } from '@/core/FileInfoService.js';
//import { DI } from '@/di-symbols.js';
import { AiService } from '@/core/AiService.js';
import { LoggerService } from '@/core/LoggerService.js';
import type { TestingModule } from '@nestjs/testing';
import type { MockFunctionMetadata } from 'jest-mock';

Expand All @@ -35,6 +36,7 @@ describe('FileInfoService', () => {
],
providers: [
AiService,
LoggerService,
FileInfoService,
],
})
Expand Down Expand Up @@ -323,8 +325,26 @@ describe('FileInfoService', () => {
});
});

/*
* video/webmとして検出されてしまう
test('MPEG-4 AUDIO (M4A)', async () => {
const path = `${resources}/kick_gaba7.m4a`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
delete info.warnings;
delete info.blurhash;
delete info.sensitive;
delete info.porn;
delete info.width;
delete info.height;
delete info.orientation;
assert.deepStrictEqual(info, {
size: 9817,
md5: '74c9279a4abe98789565f1dc1a541a42',
type: {
mime: 'audio/mp4',
ext: 'm4a',
},
});
});

test('WEBM AUDIO', async () => {
const path = `${resources}/kick_gaba7.webm`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
Expand All @@ -337,13 +357,12 @@ describe('FileInfoService', () => {
delete info.orientation;
assert.deepStrictEqual(info, {
size: 8879,
md5: '3350083dec312419cfdc06c16413aca7',
md5: '53bc1adcb6acbbda67ff9bd484896438',
type: {
mime: 'audio/webm',
ext: 'webm',
},
});
});
*/
});
});
2 changes: 0 additions & 2 deletions packages/frontend/src/components/MkCode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,9 @@ function copy() {
.codePlaceholderRoot {
display: block;
width: 100%;
background: none;
border: none;
outline: none;
font: inherit;
color: inherit;
cursor: pointer;
box-sizing: border-box;
Expand Down
7 changes: 3 additions & 4 deletions packages/frontend/src/components/MkNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<MkReactionsViewer v-if="appearNote.reactionAcceptance !== 'likeOnly'" :note="appearNote" :maxNumber="16" @mockUpdateMyReaction="emitUpdReaction">
<template #more>
<div :class="$style.reactionOmitted">{{ i18n.ts.more }}</div>
<MkA :to="`/notes/${appearNote.id}/reactions`" :class="[$style.reactionOmitted]">{{ i18n.ts.more }}</MkA>
</template>
</MkReactionsViewer>
<footer :class="$style.footer">
Expand Down Expand Up @@ -1020,9 +1020,8 @@ function emitUpdReaction(emoji: string, delta: number) {
.reactionOmitted {
display: inline-block;
height: 32px;
margin: 2px;
padding: 0 6px;
margin-left: 8px;
opacity: .8;
font-size: 95%;
}
</style>
9 changes: 6 additions & 3 deletions packages/frontend/src/components/MkNoteDetailed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,12 @@ import MkReactionIcon from '@/components/MkReactionIcon.vue';
import MkButton from '@/components/MkButton.vue';
import { isEnabledUrlPreview } from '@/instance.js';
const props = defineProps<{
const props = withDefaults(defineProps<{
note: Misskey.entities.Note;
}>();
initialTab: string;
}>(), {
initialTab: 'replies',
});
const inChannel = inject('inChannel', null);
Expand Down Expand Up @@ -304,7 +307,7 @@ provide('react', (reaction: string) => {
});
});
const tab = ref('replies');
const tab = ref(props.initialTab);
const reactionTabType = ref<string | null>(null);
const renotesPagination = computed<Paging>(() => ({
Expand Down
3 changes: 3 additions & 0 deletions packages/frontend/src/components/MkReactionsViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ watch([() => props.note.reactions, () => props.maxNumber], ([newSource, maxNumbe
}
.root {
display: flex;
flex-wrap: wrap;
align-items: center;
margin: 4px -2px 0 -2px;
&:empty {
Expand Down
15 changes: 15 additions & 0 deletions packages/frontend/src/components/page/page.block.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,28 @@ import XText from './page.text.vue';
import XSection from './page.section.vue';
import XImage from './page.image.vue';
import XNote from './page.note.vue';
import XDynamic from './page.dynamic.vue';
function getComponent(type: string) {
switch (type) {
case 'text': return XText;
case 'section': return XSection;
case 'image': return XImage;
case 'note': return XNote;
// 動的ページの代替用ブロック
case 'button':
case 'if':
case 'textarea':
case 'post':
case 'canvas':
case 'numberInput':
case 'textInput':
case 'switch':
case 'radioButton':
case 'counter':
return XDynamic;
default: return null;
}
}
Expand Down
43 changes: 43 additions & 0 deletions packages/frontend/src/components/page/page.dynamic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->

<!-- 動的ページのブロックの代替。利用できないということを表示する -->
<template>
<div :class="$style.root">
<div :class="$style.heading"><i class="ti ti-dice-5"></i> {{ i18n.ts._pages.blocks.dynamic }}</div>
<I18n :src="i18n.ts._pages.blocks.dynamicDescription" tag="div" :class="$style.text">
<template #play>
<MkA to="/play" class="_link">Play</MkA>
</template>
</I18n>
</div>
</template>

<script lang="ts" setup>
import * as Misskey from 'misskey-js';
import { i18n } from '@/i18n.js';
const props = defineProps<{
block: Misskey.entities.PageBlock,
page: Misskey.entities.Page,
}>();
</script>

<style lang="scss" module>
.root {
border: 1px solid var(--divider);
border-radius: var(--radius);
padding: var(--margin);
text-align: center;
}
.heading {
font-weight: 700;
}
.text {
font-size: 90%;
}
</style>
2 changes: 1 addition & 1 deletion packages/frontend/src/components/page/page.text.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div class="_gaps" :class="$style.textRoot">
<Mfm :text="block.text ?? ''" :isNote="false"/>
<div v-if="isEnabledUrlPreview">
<div v-if="isEnabledUrlPreview" class="_gaps_s">
<MkUrlPreview v-for="url in urls" :key="url" :url="url"/>
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/pages/note.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<div class="_margin _gaps_s">
<MkRemoteCaution v-if="note.user.host != null" :href="note.url ?? note.uri"/>
<MkNoteDetailed :key="note.id" v-model:note="note" :class="$style.note"/>
<MkNoteDetailed :key="note.id" v-model:note="note" :initialTab="initialTab" :class="$style.note"/>
</div>
<div v-if="clips && clips.length > 0" class="_margin">
<div style="font-weight: bold; padding: 12px;">{{ i18n.ts.clip }}</div>
Expand Down Expand Up @@ -66,6 +66,7 @@ import { defaultStore } from '@/store.js';
const props = defineProps<{
noteId: string;
initialTab?: string;
}>();
const note = ref<null | Misskey.entities.Note>();
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/router/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const routes: RouteDef[] = [{
component: page(() => import('@/pages/user/index.vue')),
}, {
name: 'note',
path: '/notes/:noteId',
path: '/notes/:noteId/:initialTab?',
component: page(() => import('@/pages/note.vue')),
}, {
name: 'list',
Expand Down

0 comments on commit cd220cb

Please sign in to comment.