1
1
mirror of https://github.com/kokonect-link/cherrypick synced 2024-12-18 16:48:30 +09:00

Merge remote-branch 'misskey/master'

This commit is contained in:
NoriDev 2023-07-24 16:56:01 +09:00
commit 7ad4587f60
11 changed files with 73 additions and 36 deletions

View File

@ -12,7 +12,7 @@
-->
## 13.x.x (unreleased)
## 13.14.1
### General
- 招待機能を改善しました
@ -27,6 +27,7 @@
- deck UIのカラムのメニューからアンテナとリストの編集画面を開けるように
- ドライブファイルのメニューで画像をクロップできるように
- 画像を動画と同様に簡単に隠せるように
- Enhance: ノートの埋め込みが複数画像と動画を表示されるように
- オリジナル画像を保持せずにアップロードする場合webpでアップロードされるように(Safari以外)
- 見たことのあるRenoteを省略して表示をオンのときに自分のnoteのrenoteを省略するように
- フォルダーやファイルに対しても開発者モード使用時、IDをコピーできるように
@ -42,6 +43,8 @@
- ロール設定画面でロールIDを確認できるように
- コンテキストメニュー表示時のパフォーマンスを改善
- フォロー/フォロワー非公開時の表示を改善
- 本文にMFMが含まれている場合に自動でたたまれる機能が、返信先や引用RNにも適用されるように
- position は対象外になりました
- AiScriptを0.15.0に更新
- Fix: サーバーメトリクスが90度傾いている
- Fix: 非ログイン時にクレデンシャルが必要なページに行くとエラーが出る問題を修正

View File

@ -389,10 +389,13 @@ help: "Hjälp"
close: "Stäng"
invites: "Inbjudan"
members: "Medlemmar"
transfer: "Överför"
text: "Text"
enable: "Aktivera"
next: "Nästa"
invitations: "Inbjudan"
invitationCode: "Inbjudningskod"
available: "Tillgängligt"
weakPassword: "Svagt Lösenord"
normalPassword: "Medel Lösenord"
strongPassword: "Starkt Lösenord"

View File

@ -1,7 +1,7 @@
---
_lang_: "繁體中文"
headlineMisskey: "貼文連繫網絡"
introMisskey: "歡迎! CherryPick是一個開源且去中心化的社群網絡。\n通過「貼文」分享周邊新鮮事並告訴其他人您的想法📡\n透過「情感」功能對大家的貼文表達情感👍\n一起來探索這個新的世界吧!🚀"
introMisskey: "歡迎!CherryPick 是一個開源且去中心化的社群網路服務。\n發佈「貼文」向身邊的人分享您的想法📡\n利用「反應」表達您對貼文的感覺👍\n讓我們一起探索新的世界吧!🚀"
poweredByMisskeyDescription: "{name}是使用開放原始碼平台<b>CherryPick</b>的服務之一(稱為 CherryPick 伺服器)。\n"
monthAndDay: "{month}月 {day}日"
search: "搜尋"

View File

@ -1,12 +1,12 @@
{
"name": "cherrypick",
"version": "13.14.0-beta.7-cp-4.2.0-beta.1",
"version": "13.14.1-cp-4.2.0-beta.1",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/kokonect-link/cherrypick.git"
},
"packageManager": "pnpm@8.6.0",
"packageManager": "pnpm@8.6.9",
"workspaces": [
"packages/frontend",
"packages/backend",

View File

@ -108,7 +108,7 @@ export class QueueService {
removeOnFail: true,
};
await this.deliverQueue.addBulk(Array.from(inboxes.entries()).map(d => ({
await this.deliverQueue.addBulk(Array.from(inboxes.entries(), d => ({
name: d[0],
data: {
user,

View File

@ -5,8 +5,8 @@ block vars
- const title = user.name ? `${user.name} (@${user.username})` : `@${user.username}`;
- const url = `${config.url}/notes/${note.id}`;
- const isRenote = note.renote && note.text == null && note.fileIds.length == 0 && note.poll == null;
- const image = (note.files || []).find(file => file.type.startsWith('image/') && !file.isSensitive)
- const video = (note.files || []).find(file => file.type.startsWith('video/') && !file.isSensitive)
- const images = (note.files || []).filter(file => file.type.startsWith('image/') && !file.isSensitive)
- const videos = (note.files || []).filter(file => file.type.startsWith('video/') && !file.isSensitive)
block title
= `${title} | ${instanceName}`
@ -19,14 +19,16 @@ block og
meta(property='og:title' content= title)
meta(property='og:description' content= summary)
meta(property='og:url' content= url)
if video
if videos.length
each video in videos
meta(property='og:video:url' content= video.url)
meta(property='og:video:secure_url' content= video.url)
meta(property='og:video:type' content= video.type)
// FIXME: add width and height
// FIXME: add embed player for Twitter
if image
if images.length
meta(property='twitter:card' content='summary_large_image')
each image in images
meta(property='og:image' content= image.url)
else
meta(property='twitter:card' content='summary')

View File

@ -191,6 +191,7 @@ import { claimAchievement } from '@/scripts/achievements';
import { getNoteSummary } from '@/scripts/get-note-summary';
import MkRippleEffect from '@/components/MkRippleEffect.vue';
import { showMovedDialog } from '@/scripts/show-moved-dialog';
import { shouldCollapsed, shouldMfmCollapsed } from '@/scripts/collapsed';
import { eventBus } from '@/scripts/cherrypick/eventBus';
import { mainRouter } from '@/router';
import { notePage } from '@/filters/note';
@ -238,19 +239,8 @@ let appearNote = $computed(() => isRenote ? note.renote as misskey.entities.Note
const isMyRenote = $i && ($i.id === note.userId);
const showContent = ref(false);
const urls = appearNote.text ? extractUrlFromMfm(mfm.parse(appearNote.text)) : null;
const isLong = (appearNote.cw == null && appearNote.text != null && (
(appearNote.text.split('\n').length > 9) ||
(appearNote.text.length > 500) ||
(appearNote.files.length >= 5) ||
(urls && urls.length >= 4)
));
const isMFM = (appearNote.cw == null && appearNote.text != null && (
(appearNote.text.includes('$[x2')) ||
(appearNote.text.includes('$[x3')) ||
(appearNote.text.includes('$[x4')) ||
(appearNote.text.includes('$[scale')) ||
(appearNote.text.includes('$[position'))
));
const isLong = shouldCollapsed(appearNote);
const isMFM = shouldMfmCollapsed(appearNote);
const collapsed = ref(appearNote.cw == null && (isLong || (isMFM && defaultStore.state.collapseDefault)));
const isDeleted = ref(false);
const muted = ref(checkWordMute(appearNote, $i, defaultStore.state.mutedWords));

View File

@ -32,10 +32,10 @@
</div>
</div>
</div>
<button v-if="isLong && collapsed" :class="$style.fade" class="_button" @click="collapsed = false">
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && collapsed" :class="$style.fade" class="_button" @click="collapsed = false">
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
</button>
<button v-else-if="isLong && !collapsed" :class="$style.showLess" class="_button" @click="collapsed = true">
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && !collapsed" :class="$style.showLess" class="_button" @click="collapsed = true">
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
</button>
<div v-if="showSubNoteFooterButton">
@ -101,6 +101,7 @@ import MkRippleEffect from '@/components/MkRippleEffect.vue';
import MkReactionsViewer from "@/components/MkReactionsViewer.vue";
import { i18n } from '@/i18n';
import { $i } from '@/account';
import { shouldCollapsed, shouldMfmCollapsed } from '@/scripts/collapsed';
import { defaultStore } from '@/store';
import { miLocalStorage } from '@/local-storage';
import { instance } from '@/instance';
@ -135,13 +136,10 @@ const props = defineProps<{
let note = $ref(deepClone(props.note));
const isLong =
props.note.cw == null && props.note.text != null && (
(props.note.text.split('\n').length > 9) ||
(props.note.text.length > 500)
);
const isLong = shouldCollapsed(props.note);
const isMFM = shouldMfmCollapsed(props.note);
const collapsed = $ref(isLong);
const collapsed = $ref(isLong || (isMFM && defaultStore.state.collapseDefault));
useNoteCapture({
rootEl: el,

View File

@ -28,6 +28,7 @@ const common = {
template: '<MkAd v-bind="props" />',
};
},
/* FIXME: disabled because it still didnt pass after applying #11267
async play({ canvasElement, args }) {
if (lock) {
console.warn('This test is unexpectedly running twice in parallel, fix it!');
@ -77,6 +78,7 @@ const common = {
lock = undefined;
}
},
*/
args: {
prefer: [],
specify: {

View File

@ -0,0 +1,22 @@
import * as mfm from 'cherrypick-mfm-js';
import * as misskey from 'cherrypick-js';
import {extractUrlFromMfm} from './extract-url-from-mfm';
export function shouldCollapsed(note: misskey.entities.Note): boolean {
const urls = note.text ? extractUrlFromMfm(mfm.parse(note.text)) : null;
return note.cw == null && note.text != null && (
(note.text.split('\n').length > 9) ||
(note.text.length > 500) ||
(note.files.length >= 5) ||
(!!urls && urls.length >= 4)
);
}
export function shouldMfmCollapsed(note: misskey.entities.Note): boolean {
return note.cw == null && note.text != null && (
(note.text.includes('$[x2')) ||
(note.text.includes('$[x3')) ||
(note.text.includes('$[x4')) ||
(note.text.includes('$[scale'))
);
}

View File

@ -1,3 +1,20 @@
const requestIdleCallback: typeof globalThis.requestIdleCallback = globalThis.requestIdleCallback ?? ((callback) => {
const start = performance.now();
const timeoutId = setTimeout(() => {
callback({
didTimeout: false, // polyfill でタイムアウト発火することはない
timeRemaining() {
const diff = performance.now() - start;
return Math.max(0, 50 - diff); // <https://www.w3.org/TR/requestidlecallback/#idle-periods>
},
});
});
return timeoutId;
});
const cancelIdleCallback: typeof globalThis.cancelIdleCallback = globalThis.cancelIdleCallback ?? ((timeoutId) => {
clearTimeout(timeoutId);
});
class IdlingRenderScheduler {
#renderers: Set<FrameRequestCallback>;
#rafId: number;