Merge branch 'develop' of codeberg.org:calckey/calckey into develop
This commit is contained in:
commit
a88133c4bc
7 changed files with 55 additions and 38 deletions
|
@ -4,7 +4,7 @@ import * as fs from "node:fs";
|
||||||
import { queueLogger } from "../../logger.js";
|
import { queueLogger } from "../../logger.js";
|
||||||
import { addFile } from "@/services/drive/add-file.js";
|
import { addFile } from "@/services/drive/add-file.js";
|
||||||
import { format as dateFormat } from "date-fns";
|
import { format as dateFormat } from "date-fns";
|
||||||
import { Users, Notes, Polls } from "@/models/index.js";
|
import { Users, Notes, Polls, DriveFiles } from "@/models/index.js";
|
||||||
import { MoreThan } from "typeorm";
|
import { MoreThan } from "typeorm";
|
||||||
import type { Note } from "@/models/entities/note.js";
|
import type { Note } from "@/models/entities/note.js";
|
||||||
import type { Poll } from "@/models/entities/poll.js";
|
import type { Poll } from "@/models/entities/poll.js";
|
||||||
|
@ -75,7 +75,7 @@ export async function exportNotes(
|
||||||
if (note.hasPoll) {
|
if (note.hasPoll) {
|
||||||
poll = await Polls.findOneByOrFail({ noteId: note.id });
|
poll = await Polls.findOneByOrFail({ noteId: note.id });
|
||||||
}
|
}
|
||||||
const content = JSON.stringify(serialize(note, poll));
|
const content = JSON.stringify(await serialize(note, poll));
|
||||||
const isFirst = exportedNotesCount === 0;
|
const isFirst = exportedNotesCount === 0;
|
||||||
await write(isFirst ? content : ",\n" + content);
|
await write(isFirst ? content : ",\n" + content);
|
||||||
exportedNotesCount++;
|
exportedNotesCount++;
|
||||||
|
@ -112,15 +112,16 @@ export async function exportNotes(
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialize(
|
async function serialize(
|
||||||
note: Note,
|
note: Note,
|
||||||
poll: Poll | null = null,
|
poll: Poll | null = null,
|
||||||
): Record<string, unknown> {
|
): Promise<Record<string, unknown>> {
|
||||||
return {
|
return {
|
||||||
id: note.id,
|
id: note.id,
|
||||||
text: note.text,
|
text: note.text,
|
||||||
createdAt: note.createdAt,
|
createdAt: note.createdAt,
|
||||||
fileIds: note.fileIds,
|
fileIds: note.fileIds,
|
||||||
|
files: await DriveFiles.packMany(note.fileIds),
|
||||||
replyId: note.replyId,
|
replyId: note.replyId,
|
||||||
renoteId: note.renoteId,
|
renoteId: note.renoteId,
|
||||||
poll: poll,
|
poll: poll,
|
||||||
|
|
|
@ -3,6 +3,8 @@ import create from "@/services/note/create.js";
|
||||||
import { Users } from "@/models/index.js";
|
import { Users } from "@/models/index.js";
|
||||||
import type { DbUserImportMastoPostJobData } from "@/queue/types.js";
|
import type { DbUserImportMastoPostJobData } from "@/queue/types.js";
|
||||||
import { queueLogger } from "../../logger.js";
|
import { queueLogger } from "../../logger.js";
|
||||||
|
import { uploadFromUrl } from "@/services/drive/upload-from-url.js";
|
||||||
|
import type { DriveFile } from "@/models/entities/drive-file.js";
|
||||||
import type Bull from "bull";
|
import type Bull from "bull";
|
||||||
|
|
||||||
const logger = queueLogger.createSubLogger("import-calckey-post");
|
const logger = queueLogger.createSubLogger("import-calckey-post");
|
||||||
|
@ -29,10 +31,25 @@ export async function importCkPost(
|
||||||
done();
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const urls = (post.files || [])
|
||||||
|
.map((x: any) => x.url)
|
||||||
|
.filter((x: String) => x.startsWith("http"));
|
||||||
|
const files: DriveFile[] = [];
|
||||||
|
for (const url of urls) {
|
||||||
|
try {
|
||||||
|
const file = await uploadFromUrl({
|
||||||
|
url: url,
|
||||||
|
user: user,
|
||||||
|
});
|
||||||
|
files.push(file);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`Skipped adding file to drive: ${url}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
const { text, cw, localOnly, createdAt } = Post.parse(post);
|
const { text, cw, localOnly, createdAt } = Post.parse(post);
|
||||||
const note = await create(user, {
|
const note = await create(user, {
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
files: undefined,
|
files: files.length == 0 ? undefined : files,
|
||||||
poll: undefined,
|
poll: undefined,
|
||||||
text: text || undefined,
|
text: text || undefined,
|
||||||
reply: null,
|
reply: null,
|
||||||
|
|
|
@ -6,6 +6,8 @@ import type Bull from "bull";
|
||||||
import { htmlToMfm } from "@/remote/activitypub/misc/html-to-mfm.js";
|
import { htmlToMfm } from "@/remote/activitypub/misc/html-to-mfm.js";
|
||||||
import { resolveNote } from "@/remote/activitypub/models/note.js";
|
import { resolveNote } from "@/remote/activitypub/models/note.js";
|
||||||
import { Note } from "@/models/entities/note.js";
|
import { Note } from "@/models/entities/note.js";
|
||||||
|
import { uploadFromUrl } from "@/services/drive/upload-from-url.js";
|
||||||
|
import type { DriveFile } from "@/models/entities/drive-file.js";
|
||||||
|
|
||||||
const logger = queueLogger.createSubLogger("import-masto-post");
|
const logger = queueLogger.createSubLogger("import-masto-post");
|
||||||
|
|
||||||
|
@ -43,9 +45,25 @@ export async function importMastoPost(
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
job.progress(80);
|
job.progress(80);
|
||||||
|
const urls = post.object.attachment
|
||||||
|
.map((x: any) => x.url)
|
||||||
|
.filter((x: String) => x.startsWith("http"));
|
||||||
|
const files: DriveFile[] = [];
|
||||||
|
for (const url of urls) {
|
||||||
|
try {
|
||||||
|
const file = await uploadFromUrl({
|
||||||
|
url: url,
|
||||||
|
user: user,
|
||||||
|
});
|
||||||
|
files.push(file);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`Skipped adding file to drive: ${url}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const note = await create(user, {
|
const note = await create(user, {
|
||||||
createdAt: new Date(post.object.published),
|
createdAt: new Date(post.object.published),
|
||||||
files: undefined,
|
files: files.length == 0 ? undefined : files,
|
||||||
poll: undefined,
|
poll: undefined,
|
||||||
text: text || undefined,
|
text: text || undefined,
|
||||||
reply,
|
reply,
|
||||||
|
|
|
@ -195,7 +195,7 @@ const props = withDefaults(
|
||||||
);
|
);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(ev: "chosen", v: string): void;
|
(ev: "chosen", v: string, ev: MouseEvent): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const search = ref<HTMLInputElement>();
|
const search = ref<HTMLInputElement>();
|
||||||
|
@ -436,7 +436,7 @@ function chosen(emoji: any, ev?: MouseEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = getKey(emoji);
|
const key = getKey(emoji);
|
||||||
emit("chosen", key);
|
emit("chosen", key, ev);
|
||||||
|
|
||||||
// 最近使った絵文字更新
|
// 最近使った絵文字更新
|
||||||
if (!pinned.value.includes(key)) {
|
if (!pinned.value.includes(key)) {
|
||||||
|
|
|
@ -58,29 +58,16 @@ const emit = defineEmits<{
|
||||||
|
|
||||||
const modal = ref<InstanceType<typeof MkModal>>();
|
const modal = ref<InstanceType<typeof MkModal>>();
|
||||||
const picker = ref<InstanceType<typeof MkEmojiPicker>>();
|
const picker = ref<InstanceType<typeof MkEmojiPicker>>();
|
||||||
const isShiftKeyPressed = ref(false);
|
|
||||||
|
|
||||||
const keydownHandler = (e) => {
|
|
||||||
if (e.key === "Shift") {
|
|
||||||
isShiftKeyPressed.value = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const keyupHandler = (e) => {
|
|
||||||
if (e.key === "Shift") {
|
|
||||||
isShiftKeyPressed.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function checkForShift(ev?: MouseEvent) {
|
function checkForShift(ev?: MouseEvent) {
|
||||||
if (!isShiftKeyPressed.value) {
|
if (ev?.shiftKey) return;
|
||||||
modal.value?.close(ev);
|
modal.value?.close(ev);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function chosen(emoji: any) {
|
function chosen(emoji: any, ev: MouseEvent) {
|
||||||
emit("done", emoji);
|
emit("done", emoji);
|
||||||
checkForShift();
|
checkForShift(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
function opening() {
|
function opening() {
|
||||||
|
@ -91,16 +78,6 @@ function opening() {
|
||||||
}
|
}
|
||||||
picker.value?.focus();
|
picker.value?.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
window.addEventListener("keydown", keydownHandler);
|
|
||||||
window.addEventListener("keyup", keyupHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
window.removeEventListener("keydown", keydownHandler);
|
|
||||||
window.removeEventListener("keyup", keyupHandler);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
controls
|
controls
|
||||||
@contextmenu.stop
|
@contextmenu.stop
|
||||||
>
|
>
|
||||||
<source :src="media.url" :type="media.type" />
|
<source :src="media.url" :type="mediaType" />
|
||||||
</video>
|
</video>
|
||||||
</VuePlyr>
|
</VuePlyr>
|
||||||
</template>
|
</template>
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { watch, ref } from "vue";
|
import { watch, ref, computed } from "vue";
|
||||||
import VuePlyr from "vue-plyr";
|
import VuePlyr from "vue-plyr";
|
||||||
import "vue-plyr/dist/vue-plyr.css";
|
import "vue-plyr/dist/vue-plyr.css";
|
||||||
import type * as misskey from "calckey-js";
|
import type * as misskey from "calckey-js";
|
||||||
|
@ -107,6 +107,10 @@ const url =
|
||||||
? getStaticImageUrl(props.media.thumbnailUrl)
|
? getStaticImageUrl(props.media.thumbnailUrl)
|
||||||
: props.media.thumbnailUrl;
|
: props.media.thumbnailUrl;
|
||||||
|
|
||||||
|
const mediaType = computed(() => {
|
||||||
|
return props.media.type === 'video/quicktime' ? 'video/mp4' : props.media.type;
|
||||||
|
});
|
||||||
|
|
||||||
function captionPopup() {
|
function captionPopup() {
|
||||||
os.alert({
|
os.alert({
|
||||||
type: "info",
|
type: "info",
|
||||||
|
|
|
@ -222,7 +222,7 @@ const importPosts = async (ev) => {
|
||||||
const file = await selectFile(ev.currentTarget ?? ev.target);
|
const file = await selectFile(ev.currentTarget ?? ev.target);
|
||||||
os.api("i/import-posts", {
|
os.api("i/import-posts", {
|
||||||
fileId: file.id,
|
fileId: file.id,
|
||||||
signatureCheck: importType.value === "mastodon" ? true : false,
|
signatureCheck: false,
|
||||||
})
|
})
|
||||||
.then(onImportSuccess)
|
.then(onImportSuccess)
|
||||||
.catch(onError);
|
.catch(onError);
|
||||||
|
|
Loading…
Reference in a new issue