Merge remote-tracking branch 'misskey-original/develop' into develop

# Conflicts:
#	locales/en-US.yml
#	locales/index.d.ts
#	locales/ja-JP.yml
#	package.json
#	packages/backend/src/server/api/endpoints/notes/create.ts
#	packages/frontend/src/components/MkDrive.file.vue
#	packages/frontend/src/components/MkNote.vue
#	packages/frontend/src/components/MkNoteHeader.vue
#	packages/frontend/src/components/MkPostForm.vue
#	packages/frontend/src/components/MkReactionsViewer.reaction.vue
#	packages/frontend/src/components/MkUserSetupDialog.vue
#	packages/frontend/src/pages/timeline.tutorial.vue
#	packages/frontend/src/pages/timeline.vue
#	packages/misskey-js/etc/misskey-js.api.md
This commit is contained in:
mattyatea 2023-11-04 01:24:44 +09:00
commit cb1005811d
106 changed files with 2036 additions and 963 deletions

View file

@ -100,7 +100,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import {inject, watch, nextTick, onMounted, defineAsyncComponent, computed, ref} from 'vue';
import { inject, watch, nextTick, onMounted, defineAsyncComponent , computed, ref , provide } from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
import insertTextAtCursor from 'insert-text-at-cursor';
@ -139,31 +139,38 @@ let gamingType = computed(defaultStore.makeGetterSetter('gamingType'));
const props = withDefaults(defineProps<{
reply?: Misskey.entities.Note;
renote?: Misskey.entities.Note;
channel?: Misskey.entities.Channel; // TODO
mention?: Misskey.entities.User;
specified?: Misskey.entities.User;
initialText?: string;
initialVisibility?: (typeof Misskey.noteVisibilities)[number];
initialFiles?: Misskey.entities.DriveFile[];
initialLocalOnly?: boolean;
initialVisibleUsers?: Misskey.entities.User[];
initialNote?: Misskey.entities.Note;
instant?: boolean;
fixed?: boolean;
autofocus?: boolean;
freezeAfterPosted?: boolean;
updateMode?: boolean;
reply?: Misskey.entities.Note;
renote?: Misskey.entities.Note;
channel?: Misskey.entities.Channel; // TODO
mention?: Misskey.entities.User;
specified?: Misskey.entities.User;
initialText?: string;
initialVisibility?: (typeof Misskey.noteVisibilities)[number];
initialFiles?: Misskey.entities.DriveFile[];
initialLocalOnly?: boolean;
initialVisibleUsers?: Misskey.entities.User[];
initialNote?: Misskey.entities.Note;
instant?: boolean;
fixed?: boolean;
autofocus?: boolean;
freezeAfterPosted?: boolean;
mock?: boolean;
updateMode?: boolean;
}>(), {
initialVisibleUsers: () => [],
autofocus: true,
mock: false,
});
provide('mock', props.mock);
const emit = defineEmits<{
(ev: 'posted'): void;
(ev: 'cancel'): void;
(ev: 'esc'): void;
// Mock
(ev: 'fileChangeSensitive', fileId: string, to: boolean): void;
}>();
const textareaEl = $shallowRef<HTMLTextAreaElement | null>(null);
@ -251,7 +258,7 @@ const maxTextLength = $computed((): number => {
});
const canPost = $computed((): boolean => {
return !posting && !posted &&
return !props.mock && !posting && !posted &&
(1 <= textLength || 1 <= files.length || !!poll || !!props.renote) &&
(textLength <= maxTextLength) &&
(!poll || poll.choices.length >= 2);
@ -304,6 +311,10 @@ if (props.reply && props.reply.text != null) {
}
}
if ($i?.isSilenced && visibility === 'public') {
visibility = 'home';
}
if (props.channel) {
visibility = 'public';
localOnly = true; // TODO:
@ -408,7 +419,7 @@ function focus() {
}
function chooseFileFrom(ev) {
selectFiles(ev.currentTarget ?? ev.target, i18n.ts.attachFile).then(files_ => {
if (props.mock) return;selectFiles(ev.currentTarget ?? ev.target, i18n.ts.attachFile).then(files_ => {
for (const file of files_) {
files.push(file);
}
@ -420,7 +431,10 @@ function detachFile(id) {
}
function updateFileSensitive(file, sensitive) {
files[files.findIndex(x => x.id === file.id)].isSensitive = sensitive;
if (props.mock) {
emit('fileChangeSensitive', file.id, sensitive);
}
files[files.findIndex(x => x.id === file.id)].isSensitive = sensitive;
}
function updateFileName(file, name) {
@ -432,7 +446,7 @@ function replaceFile(file: Misskey.entities.DriveFile, newFile: Misskey.entities
}
function upload(file: File, name?: string): void {
uploadFile(file, defaultStore.state.uploadFolder, name).then(res => {
if (props.mock) return;uploadFile(file, defaultStore.state.uploadFolder, name).then(res => {
files.push(res);
});
}
@ -446,7 +460,7 @@ function setVisibility() {
os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), {
currentVisibility: visibility,
localOnly: localOnly,
isSilenced: $i?.isSilenced,localOnly: localOnly,
src: visibilityButton,
}, {
changeVisibility: v => {
@ -557,7 +571,7 @@ function onCompositionEnd(ev: CompositionEvent) {
}
async function onPaste(ev: ClipboardEvent) {
for (const { item, i } of Array.from(ev.clipboardData.items, (item, i) => ({ item, i }))) {
if (props.mock) return;for (const { item, i } of Array.from(ev.clipboardData.items, (item, i) => ({ item, i }))) {
if (item.kind === 'file') {
const file = item.getAsFile();
const lio = file.name.lastIndexOf('.');
@ -641,7 +655,7 @@ function onDrop(ev): void {
}
function saveDraft() {
if (props.instant) return;
if (props.instant || props.mock) return;
const draftData = JSON.parse(miLocalStorage.getItem('drafts') ?? '{}');
@ -670,7 +684,13 @@ function deleteDraft() {
}
async function post(ev?: MouseEvent) {
if (ev) {
if (useCw && (cw == null || cw.trim() === '')) {
os.alert({
type: 'error',
text: i18n.ts.cwNotationRequired,
});
return;
}if (ev) {
const el = ev.currentTarget ?? ev.target;
const rect = el.getBoundingClientRect();
const x = rect.left + (el.offsetWidth / 2);
@ -678,7 +698,7 @@ async function post(ev?: MouseEvent) {
os.popup(MkRippleEffect, { x, y }, {}, 'end');
}
const annoying =
if (props.mock) return;const annoying =
text.includes('$[x2') ||
text.includes('$[x3') ||
text.includes('$[x4') ||
@ -850,7 +870,7 @@ function showActions(ev) {
let postAccount = $ref<Misskey.entities.UserDetailed | null>(null);
function openAccountMenu(ev: MouseEvent) {
openAccountMenu_({
if (props.mock) return;openAccountMenu_({
withExtraOperation: false,
includeCurrentAccount: true,
active: postAccount != null ? postAccount.id : $i.id,
@ -880,7 +900,7 @@ onMounted(() => {
nextTick(() => {
// 稿
if (!props.instant && !props.mention && !props.specified) {
if (!props.instant && !props.mention && !props.specified && !props.mock) {
const draft = JSON.parse(miLocalStorage.getItem('drafts') ?? '{}')[draftKey];
if (draft) {
text = draft.data.text;