Merge branch 'develop' of https://github.com/transfem-org/Sharkey into develop
This commit is contained in:
commit
a707b410d0
10 changed files with 97 additions and 43 deletions
2
.github/workflows/welcome.yml
vendored
2
.github/workflows/welcome.yml
vendored
|
@ -8,7 +8,7 @@ jobs:
|
||||||
run:
|
run:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/first-interaction@v1.2.0
|
- uses: actions/first-interaction@v1.3.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
issue-message: |
|
issue-message: |
|
||||||
|
|
|
@ -988,6 +988,7 @@ cannotLoad: "Unable to load"
|
||||||
numberOfProfileView: "Profile views"
|
numberOfProfileView: "Profile views"
|
||||||
like: "Like"
|
like: "Like"
|
||||||
unlike: "Unlike"
|
unlike: "Unlike"
|
||||||
|
defaultLike: "Default like emoji"
|
||||||
numberOfLikes: "Likes"
|
numberOfLikes: "Likes"
|
||||||
show: "Show"
|
show: "Show"
|
||||||
neverShow: "Don't show again"
|
neverShow: "Don't show again"
|
||||||
|
@ -1856,6 +1857,14 @@ _ago:
|
||||||
monthsAgo: "{n}mo ago"
|
monthsAgo: "{n}mo ago"
|
||||||
yearsAgo: "{n}y ago"
|
yearsAgo: "{n}y ago"
|
||||||
invalid: "None"
|
invalid: "None"
|
||||||
|
_timeIn:
|
||||||
|
seconds: "in {n} seconds"
|
||||||
|
minutes: "in {n} minutes"
|
||||||
|
hours: "in {n} hours"
|
||||||
|
days: "in {n} days"
|
||||||
|
weeks: "in {n} weeks"
|
||||||
|
months: "in {n} months"
|
||||||
|
years: "in {n} years"
|
||||||
_time:
|
_time:
|
||||||
second: "Second(s)"
|
second: "Second(s)"
|
||||||
minute: "Minute(s)"
|
minute: "Minute(s)"
|
||||||
|
|
1
locales/index.d.ts
vendored
1
locales/index.d.ts
vendored
|
@ -991,6 +991,7 @@ export interface Locale {
|
||||||
"numberOfProfileView": string;
|
"numberOfProfileView": string;
|
||||||
"like": string;
|
"like": string;
|
||||||
"unlike": string;
|
"unlike": string;
|
||||||
|
"defaultLike": string;
|
||||||
"numberOfLikes": string;
|
"numberOfLikes": string;
|
||||||
"show": string;
|
"show": string;
|
||||||
"neverShow": string;
|
"neverShow": string;
|
||||||
|
|
|
@ -54,6 +54,7 @@ addToAntenna: "Aggiungi all'antenna"
|
||||||
sendMessage: "Invia messaggio"
|
sendMessage: "Invia messaggio"
|
||||||
copyRSS: "Copia RSS"
|
copyRSS: "Copia RSS"
|
||||||
copyUsername: "Copia nome utente"
|
copyUsername: "Copia nome utente"
|
||||||
|
openRemoteProfile: "Apri profilo remoto"
|
||||||
copyUserId: "Copia ID del profilo"
|
copyUserId: "Copia ID del profilo"
|
||||||
copyNoteId: "Copia ID della Nota"
|
copyNoteId: "Copia ID della Nota"
|
||||||
copyFileId: "Copia ID del file"
|
copyFileId: "Copia ID del file"
|
||||||
|
@ -731,6 +732,8 @@ thisIsExperimentalFeature: "Questa è una funzionalità sperimentale. Potrebbe e
|
||||||
developer: "Sviluppatore"
|
developer: "Sviluppatore"
|
||||||
makeExplorable: "Profilo visibile pubblicamente nella pagina \"Esplora\""
|
makeExplorable: "Profilo visibile pubblicamente nella pagina \"Esplora\""
|
||||||
makeExplorableDescription: "Disabilitando questa opzione, il tuo profilo non verrà elencato nella pagina \"Esplora\"."
|
makeExplorableDescription: "Disabilitando questa opzione, il tuo profilo non verrà elencato nella pagina \"Esplora\"."
|
||||||
|
makeIndexable: "Non indicizzare le note pubbliche"
|
||||||
|
makeIndexableDescription: "Le tue note pubbliche non saranno cercabili"
|
||||||
showGapBetweenNotesInTimeline: "Mostrare un intervallo tra le note sulla timeline"
|
showGapBetweenNotesInTimeline: "Mostrare un intervallo tra le note sulla timeline"
|
||||||
duplicate: "Duplica"
|
duplicate: "Duplica"
|
||||||
left: "Sinistra"
|
left: "Sinistra"
|
||||||
|
@ -964,6 +967,7 @@ cannotLoad: "Caricamento impossibile"
|
||||||
numberOfProfileView: "Visualizzazioni profilo"
|
numberOfProfileView: "Visualizzazioni profilo"
|
||||||
like: "Mi piace!"
|
like: "Mi piace!"
|
||||||
unlike: "Non mi piace"
|
unlike: "Non mi piace"
|
||||||
|
defaultLike: "Emoji predefinita per \"mi piace\""
|
||||||
numberOfLikes: "Numero di Like"
|
numberOfLikes: "Numero di Like"
|
||||||
show: "Visualizza"
|
show: "Visualizza"
|
||||||
neverShow: "Non mostrare più"
|
neverShow: "Non mostrare più"
|
||||||
|
@ -1266,6 +1270,8 @@ _serverSettings:
|
||||||
shortName: "Abbreviazione"
|
shortName: "Abbreviazione"
|
||||||
shortNameDescription: "Un'abbreviazione o un nome comune che può essere visualizzato al posto del nome ufficiale lungo del server."
|
shortNameDescription: "Un'abbreviazione o un nome comune che può essere visualizzato al posto del nome ufficiale lungo del server."
|
||||||
fanoutTimelineDescription: "Attivando questa funzionalità migliori notevolmente la capacità delle Timeline di collezionare Note, riducendo il carico sul database. Tuttavia, aumenterà l'impiego di memoria RAM per Redis. Disattiva se il tuo server ha poca RAM o la funzionalità è irregolare."
|
fanoutTimelineDescription: "Attivando questa funzionalità migliori notevolmente la capacità delle Timeline di collezionare Note, riducendo il carico sul database. Tuttavia, aumenterà l'impiego di memoria RAM per Redis. Disattiva se il tuo server ha poca RAM o la funzionalità è irregolare."
|
||||||
|
fanoutTimelineDbFallback: "Ripiega sul database"
|
||||||
|
fanoutTimelineDbFallbackDescription: "Attivando questa funzionalità, nel caso che il contenuto di una Timeline non sia presente nella cache, verrà consultato il database. Disattivandola, il carico sul database sarà ulteriormente ridotto, ma le Timeline saranno limitate"
|
||||||
_accountMigration:
|
_accountMigration:
|
||||||
moveFrom: "Migra un altro profilo dentro a questo"
|
moveFrom: "Migra un altro profilo dentro a questo"
|
||||||
moveFromSub: "Crea un alias verso un altro profilo remoto"
|
moveFromSub: "Crea un alias verso un altro profilo remoto"
|
||||||
|
@ -1702,6 +1708,7 @@ _serverDisconnectedBehavior:
|
||||||
reload: "Ricarica automaticamente"
|
reload: "Ricarica automaticamente"
|
||||||
dialog: "Apri avviso in finestra"
|
dialog: "Apri avviso in finestra"
|
||||||
quiet: "Visualizza avviso in modo discreto"
|
quiet: "Visualizza avviso in modo discreto"
|
||||||
|
disabled: "Non visualizzare l'avviso"
|
||||||
_channel:
|
_channel:
|
||||||
create: "Nuovo canale"
|
create: "Nuovo canale"
|
||||||
edit: "Gerisci canale"
|
edit: "Gerisci canale"
|
||||||
|
@ -1817,6 +1824,14 @@ _ago:
|
||||||
monthsAgo: "{n} mesi fa"
|
monthsAgo: "{n} mesi fa"
|
||||||
yearsAgo: "{n} anni fa"
|
yearsAgo: "{n} anni fa"
|
||||||
invalid: "Niente da visualizzare"
|
invalid: "Niente da visualizzare"
|
||||||
|
_timeIn:
|
||||||
|
seconds: "fra {n} secondi"
|
||||||
|
minutes: "fra {n} minuti"
|
||||||
|
hours: "fra {n} ore"
|
||||||
|
days: "fra {n} giorni"
|
||||||
|
weeks: "fra {n} settimane"
|
||||||
|
months: "fra {n} mesi"
|
||||||
|
years: "fra {n} anni"
|
||||||
_time:
|
_time:
|
||||||
second: "s"
|
second: "s"
|
||||||
minute: "min"
|
minute: "min"
|
||||||
|
|
|
@ -988,6 +988,7 @@ cannotLoad: "読み込めません"
|
||||||
numberOfProfileView: "プロフィール表示回数"
|
numberOfProfileView: "プロフィール表示回数"
|
||||||
like: "いいね!"
|
like: "いいね!"
|
||||||
unlike: "いいねを解除"
|
unlike: "いいねを解除"
|
||||||
|
defaultLike: "絵文字のようなデフォルト"
|
||||||
numberOfLikes: "いいね数"
|
numberOfLikes: "いいね数"
|
||||||
show: "表示"
|
show: "表示"
|
||||||
neverShow: "今後表示しない"
|
neverShow: "今後表示しない"
|
||||||
|
@ -2406,7 +2407,7 @@ _externalResourceInstaller:
|
||||||
_themeInstallFailed:
|
_themeInstallFailed:
|
||||||
title: "テーマのインストールに失敗しました"
|
title: "テーマのインストールに失敗しました"
|
||||||
description: "テーマのインストール中に問題が発生しました。もう一度お試しください。エラーの詳細はJavascriptコンソールをご覧ください。"
|
description: "テーマのインストール中に問題が発生しました。もう一度お試しください。エラーの詳細はJavascriptコンソールをご覧ください。"
|
||||||
|
|
||||||
_animatedMFM:
|
_animatedMFM:
|
||||||
play: "MFMアニメーションを再生"
|
play: "MFMアニメーションを再生"
|
||||||
stop: "MFMアニメーション停止"
|
stop: "MFMアニメーション停止"
|
||||||
|
|
|
@ -278,14 +278,14 @@ export class QueueService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public createImportMastoToDbJob(user: ThinUser, targets: string[]) {
|
public createImportMastoToDbJob(user: ThinUser, targets: string[], note: MiNote['id'] | null) {
|
||||||
const jobs = targets.map(rel => this.generateToDbJobData('importMastoToDb', { user, target: rel }));
|
const jobs = targets.map(rel => this.generateToDbJobData('importMastoToDb', { user, target: rel, note }));
|
||||||
return this.dbQueue.addBulk(jobs);
|
return this.dbQueue.addBulk(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public createImportPleroToDbJob(user: ThinUser, targets: string[]) {
|
public createImportPleroToDbJob(user: ThinUser, targets: string[], note: MiNote['id'] | null) {
|
||||||
const jobs = targets.map(rel => this.generateToDbJobData('importPleroToDb', { user, target: rel }));
|
const jobs = targets.map(rel => this.generateToDbJobData('importPleroToDb', { user, target: rel, note }));
|
||||||
return this.dbQueue.addBulk(jobs);
|
return this.dbQueue.addBulk(jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { extractApHashtagObjects } from '@/core/activitypub/models/tag.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
import type { DbNoteImportToDbJobData, DbNoteImportJobData, DbKeyNoteImportToDbJobData } from '../types.js';
|
import type { DbNoteImportToDbJobData, DbNoteImportJobData, DbNoteWithParentImportToDbJobData } from '../types.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImportNotesProcessorService {
|
export class ImportNotesProcessorService {
|
||||||
|
@ -74,7 +74,7 @@ export class ImportNotesProcessorService {
|
||||||
|
|
||||||
// Function was taken from Firefish and modified for our needs
|
// Function was taken from Firefish and modified for our needs
|
||||||
@bindThis
|
@bindThis
|
||||||
private async recreateChain(idField: string, replyField: string, arr: any[]): Promise<any[]> {
|
private async recreateChain(idFieldPath: string[], replyFieldPath: string[], arr: any[], includeOrphans: boolean): Promise<any[]> {
|
||||||
type NotesMap = {
|
type NotesMap = {
|
||||||
[id: string]: any;
|
[id: string]: any;
|
||||||
};
|
};
|
||||||
|
@ -83,28 +83,42 @@ export class ImportNotesProcessorService {
|
||||||
const notesWaitingForParent: NotesMap = {};
|
const notesWaitingForParent: NotesMap = {};
|
||||||
|
|
||||||
for await (const note of arr) {
|
for await (const note of arr) {
|
||||||
noteById[note[idField]] = note;
|
const noteId = idFieldPath.reduce(
|
||||||
|
(obj, step) => obj[step],
|
||||||
|
note,
|
||||||
|
);
|
||||||
|
|
||||||
|
noteById[noteId] = note;
|
||||||
note.childNotes = [];
|
note.childNotes = [];
|
||||||
|
|
||||||
const children = notesWaitingForParent[note[idField]];
|
const children = notesWaitingForParent[noteId];
|
||||||
if (children) {
|
if (children) {
|
||||||
note.childNotes.push(...children);
|
note.childNotes.push(...children);
|
||||||
|
delete notesWaitingForParent[noteId];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (note[replyField] == null) {
|
const noteReplyId = replyFieldPath.reduce(
|
||||||
|
(obj, step) => obj[step],
|
||||||
|
note,
|
||||||
|
);
|
||||||
|
if (noteReplyId == null) {
|
||||||
notesTree.push(note);
|
notesTree.push(note);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = noteById[note[replyField]];
|
const parent = noteById[noteReplyId];
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent.childNotes.push(note);
|
parent.childNotes.push(note);
|
||||||
} else {
|
} else {
|
||||||
notesWaitingForParent[note[replyField]] ||= [];
|
notesWaitingForParent[noteReplyId] ||= [];
|
||||||
notesWaitingForParent[note[replyField]].push(note);
|
notesWaitingForParent[noteReplyId].push(note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (includeOrphans) {
|
||||||
|
notesTree.push(...Object.values(notesWaitingForParent).flat(1));
|
||||||
|
}
|
||||||
|
|
||||||
return notesTree;
|
return notesTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +190,7 @@ export class ImportNotesProcessorService {
|
||||||
const tweets = Object.keys(fakeWindow.window.YTD.tweets.part0).reduce((m, key, i, obj) => {
|
const tweets = Object.keys(fakeWindow.window.YTD.tweets.part0).reduce((m, key, i, obj) => {
|
||||||
return m.concat(fakeWindow.window.YTD.tweets.part0[key].tweet);
|
return m.concat(fakeWindow.window.YTD.tweets.part0[key].tweet);
|
||||||
}, []);
|
}, []);
|
||||||
const processedTweets = await this.recreateChain('id_str', 'in_reply_to_status_id_str', tweets);
|
const processedTweets = await this.recreateChain(['id_str'], ['in_reply_to_status_id_str'], tweets, false);
|
||||||
this.queueService.createImportTweetsToDbJob(job.data.user, processedTweets, null);
|
this.queueService.createImportTweetsToDbJob(job.data.user, processedTweets, null);
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
@ -254,7 +268,8 @@ export class ImportNotesProcessorService {
|
||||||
if (isPleroma) {
|
if (isPleroma) {
|
||||||
const outboxJson = fs.readFileSync(outputPath + '/outbox.json', 'utf-8');
|
const outboxJson = fs.readFileSync(outputPath + '/outbox.json', 'utf-8');
|
||||||
const outbox = JSON.parse(outboxJson);
|
const outbox = JSON.parse(outboxJson);
|
||||||
this.queueService.createImportPleroToDbJob(job.data.user, outbox.orderedItems.filter((x: any) => x.type === 'Create' && x.object.type === 'Note'));
|
const processedToots = await this.recreateChain(['object', 'id'], ['object', 'inReplyTo'], outbox.orderedItems.filter((x: any) => x.type === 'Create' && x.object.type === 'Note'), true);
|
||||||
|
this.queueService.createImportPleroToDbJob(job.data.user, processedToots, null);
|
||||||
} else {
|
} else {
|
||||||
const outboxJson = fs.readFileSync(outputPath + '/outbox.json', 'utf-8');
|
const outboxJson = fs.readFileSync(outputPath + '/outbox.json', 'utf-8');
|
||||||
const outbox = JSON.parse(outboxJson);
|
const outbox = JSON.parse(outboxJson);
|
||||||
|
@ -266,7 +281,8 @@ export class ImportNotesProcessorService {
|
||||||
if (fs.existsSync(outputPath + '/media_attachments/files') && mastoFolder) {
|
if (fs.existsSync(outputPath + '/media_attachments/files') && mastoFolder) {
|
||||||
await this.uploadFiles(outputPath + '/media_attachments/files', user, mastoFolder.id);
|
await this.uploadFiles(outputPath + '/media_attachments/files', user, mastoFolder.id);
|
||||||
}
|
}
|
||||||
this.queueService.createImportMastoToDbJob(job.data.user, outbox.orderedItems.filter((x: any) => x.type === 'Create' && x.object.type === 'Note'));
|
const processedToots = await this.recreateChain(['object', 'id'], ['object', 'inReplyTo'], outbox.orderedItems.filter((x: any) => x.type === 'Create' && x.object.type === 'Note'), true);
|
||||||
|
this.queueService.createImportMastoToDbJob(job.data.user, processedToots, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -289,7 +305,7 @@ export class ImportNotesProcessorService {
|
||||||
|
|
||||||
const notesJson = fs.readFileSync(path, 'utf-8');
|
const notesJson = fs.readFileSync(path, 'utf-8');
|
||||||
const notes = JSON.parse(notesJson);
|
const notes = JSON.parse(notesJson);
|
||||||
const processedNotes = await this.recreateChain('id', 'replyId', notes);
|
const processedNotes = await this.recreateChain(['id'], ['replyId'], notes, false);
|
||||||
this.queueService.createImportKeyNotesToDbJob(job.data.user, processedNotes, null);
|
this.queueService.createImportKeyNotesToDbJob(job.data.user, processedNotes, null);
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
@ -298,7 +314,7 @@ export class ImportNotesProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async processKeyNotesToDb(job: Bull.Job<DbKeyNoteImportToDbJobData>): Promise<void> {
|
public async processKeyNotesToDb(job: Bull.Job<DbNoteWithParentImportToDbJobData>): Promise<void> {
|
||||||
const note = job.data.target;
|
const note = job.data.target;
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
@ -355,28 +371,33 @@ export class ImportNotesProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async processMastoToDb(job: Bull.Job<DbNoteImportToDbJobData>): Promise<void> {
|
public async processMastoToDb(job: Bull.Job<DbNoteWithParentImportToDbJobData>): Promise<void> {
|
||||||
const toot = job.data.target;
|
const toot = job.data.target;
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (toot.directMessage) return;
|
||||||
|
|
||||||
const date = new Date(toot.object.published);
|
const date = new Date(toot.object.published);
|
||||||
let text = undefined;
|
let text = undefined;
|
||||||
const files: MiDriveFile[] = [];
|
const files: MiDriveFile[] = [];
|
||||||
let reply: MiNote | null = null;
|
let reply: MiNote | null = null;
|
||||||
|
|
||||||
if (toot.object.inReplyTo != null) {
|
if (toot.object.inReplyTo != null) {
|
||||||
try {
|
const parentNote = job.data.note ? await this.notesRepository.findOneBy({ id: job.data.note }) : null;
|
||||||
reply = await this.apNoteService.resolveNote(toot.object.inReplyTo);
|
if (parentNote) {
|
||||||
} catch (error) {
|
reply = parentNote;
|
||||||
reply = null;
|
} else {
|
||||||
|
try {
|
||||||
|
reply = await this.apNoteService.resolveNote(toot.object.inReplyTo);
|
||||||
|
} catch (error) {
|
||||||
|
reply = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toot.directMessage) return;
|
|
||||||
|
|
||||||
const hashtags = extractApHashtagObjects(toot.object.tag).map((x) => x.name).filter((x): x is string => x != null);
|
const hashtags = extractApHashtagObjects(toot.object.tag).map((x) => x.name).filter((x): x is string => x != null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -396,17 +417,20 @@ export class ImportNotesProcessorService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.noteCreateService.import(user, { createdAt: date, text: text, files: files, apMentions: new Array(0), cw: toot.object.sensitive ? toot.object.summary : null, reply: reply });
|
const createdNote = await this.noteCreateService.import(user, { createdAt: date, text: text, files: files, apMentions: new Array(0), cw: toot.object.sensitive ? toot.object.summary : null, reply: reply });
|
||||||
|
if (toot.childNotes) this.queueService.createImportMastoToDbJob(user, toot.childNotes, createdNote.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async processPleroToDb(job: Bull.Job<DbNoteImportToDbJobData>): Promise<void> {
|
public async processPleroToDb(job: Bull.Job<DbNoteWithParentImportToDbJobData>): Promise<void> {
|
||||||
const post = job.data.target;
|
const post = job.data.target;
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (post.directMessage) return;
|
||||||
|
|
||||||
const date = new Date(post.object.published);
|
const date = new Date(post.object.published);
|
||||||
let text = undefined;
|
let text = undefined;
|
||||||
const files: MiDriveFile[] = [];
|
const files: MiDriveFile[] = [];
|
||||||
|
@ -416,15 +440,18 @@ export class ImportNotesProcessorService {
|
||||||
if (folder == null) return;
|
if (folder == null) return;
|
||||||
|
|
||||||
if (post.object.inReplyTo != null) {
|
if (post.object.inReplyTo != null) {
|
||||||
try {
|
const parentNote = job.data.note ? await this.notesRepository.findOneBy({ id: job.data.note }) : null;
|
||||||
reply = await this.apNoteService.resolveNote(post.object.inReplyTo);
|
if (parentNote) {
|
||||||
} catch (error) {
|
reply = parentNote;
|
||||||
reply = null;
|
} else {
|
||||||
|
try {
|
||||||
|
reply = await this.apNoteService.resolveNote(post.object.inReplyTo);
|
||||||
|
} catch (error) {
|
||||||
|
reply = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (post.directMessage) return;
|
|
||||||
|
|
||||||
const hashtags = extractApHashtagObjects(post.object.tag).map((x) => x.name).filter((x): x is string => x != null);
|
const hashtags = extractApHashtagObjects(post.object.tag).map((x) => x.name).filter((x): x is string => x != null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -468,7 +495,8 @@ export class ImportNotesProcessorService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.noteCreateService.import(user, { createdAt: date, text: text, files: files, apMentions: new Array(0), cw: post.object.sensitive ? post.object.summary : null, reply: reply });
|
const createdNote = await this.noteCreateService.import(user, { createdAt: date, text: text, files: files, apMentions: new Array(0), cw: post.object.sensitive ? post.object.summary : null, reply: reply });
|
||||||
|
if (post.childNotes) this.queueService.createImportPleroToDbJob(user, post.childNotes, createdNote.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
@ -517,7 +545,7 @@ export class ImportNotesProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async processTwitterDb(job: Bull.Job<DbKeyNoteImportToDbJobData>): Promise<void> {
|
public async processTwitterDb(job: Bull.Job<DbNoteWithParentImportToDbJobData>): Promise<void> {
|
||||||
const tweet = job.data.target;
|
const tweet = job.data.target;
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
|
|
@ -50,12 +50,12 @@ export type DbJobMap = {
|
||||||
exportUserLists: DbJobDataWithUser;
|
exportUserLists: DbJobDataWithUser;
|
||||||
importAntennas: DBAntennaImportJobData;
|
importAntennas: DBAntennaImportJobData;
|
||||||
importNotes: DbNoteImportJobData;
|
importNotes: DbNoteImportJobData;
|
||||||
importTweetsToDb: DbKeyNoteImportToDbJobData;
|
importTweetsToDb: DbNoteWithParentImportToDbJobData;
|
||||||
importIGToDb: DbNoteImportToDbJobData;
|
importIGToDb: DbNoteImportToDbJobData;
|
||||||
importFBToDb: DbNoteImportToDbJobData;
|
importFBToDb: DbNoteImportToDbJobData;
|
||||||
importMastoToDb: DbNoteImportToDbJobData;
|
importMastoToDb: DbNoteWithParentImportToDbJobData;
|
||||||
importPleroToDb: DbNoteImportToDbJobData;
|
importPleroToDb: DbNoteWithParentImportToDbJobData;
|
||||||
importKeyNotesToDb: DbKeyNoteImportToDbJobData;
|
importKeyNotesToDb: DbNoteWithParentImportToDbJobData;
|
||||||
importFollowing: DbUserImportJobData;
|
importFollowing: DbUserImportJobData;
|
||||||
importFollowingToDb: DbUserImportToDbJobData;
|
importFollowingToDb: DbUserImportToDbJobData;
|
||||||
importMuting: DbUserImportJobData;
|
importMuting: DbUserImportJobData;
|
||||||
|
@ -113,7 +113,7 @@ export type DbNoteImportToDbJobData = {
|
||||||
target: any;
|
target: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DbKeyNoteImportToDbJobData = {
|
export type DbNoteWithParentImportToDbJobData = {
|
||||||
user: ThinUser;
|
user: ThinUser;
|
||||||
target: any;
|
target: any;
|
||||||
note: MiNote['id'] | null;
|
note: MiNote['id'] | null;
|
||||||
|
|
|
@ -48,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkInput>
|
</MkInput>
|
||||||
|
|
||||||
<FromSlot>
|
<FromSlot>
|
||||||
<template #label>Default like emoji</template>
|
<template #label>{{ i18n.ts.defaultLike }}</template>
|
||||||
<MkCustomEmoji v-if="defaultLike.startsWith(':')" style="max-height: 3em; font-size: 1.1em;" :useOriginalSize="false" :class="$style.reaction" :name="defaultLike" :normal="true" :noStyle="true"/>
|
<MkCustomEmoji v-if="defaultLike.startsWith(':')" style="max-height: 3em; font-size: 1.1em;" :useOriginalSize="false" :class="$style.reaction" :name="defaultLike" :normal="true" :noStyle="true"/>
|
||||||
<MkEmoji v-else :emoji="defaultLike" style="max-height: 3em; font-size: 1.1em;" :normal="true" :noStyle="true"/>
|
<MkEmoji v-else :emoji="defaultLike" style="max-height: 3em; font-size: 1.1em;" :normal="true" :noStyle="true"/>
|
||||||
<MkButton rounded :small="true" @click="chooseNewLike"><i class="ph-smiley ph-bold ph-lg"></i> Change</MkButton>
|
<MkButton rounded :small="true" @click="chooseNewLike"><i class="ph-smiley ph-bold ph-lg"></i> Change</MkButton>
|
||||||
|
|
|
@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</FromSlot>
|
</FromSlot>
|
||||||
|
|
||||||
<FromSlot>
|
<FromSlot>
|
||||||
<template #label>Default like emoji</template>
|
<template #label>{{ i18n.ts.defaultLike }}</template>
|
||||||
<MkCustomEmoji v-if="like && like.startsWith(':')" style="max-height: 3em; font-size: 1.1em;" :useOriginalSize="false" :class="$style.reaction" :name="like" :normal="true" :noStyle="true"/>
|
<MkCustomEmoji v-if="like && like.startsWith(':')" style="max-height: 3em; font-size: 1.1em;" :useOriginalSize="false" :class="$style.reaction" :name="like" :normal="true" :noStyle="true"/>
|
||||||
<MkEmoji v-else-if="like && !like.startsWith(':')" :emoji="like" style="max-height: 3em; font-size: 1.1em;" :normal="true" :noStyle="true"/>
|
<MkEmoji v-else-if="like && !like.startsWith(':')" :emoji="like" style="max-height: 3em; font-size: 1.1em;" :normal="true" :noStyle="true"/>
|
||||||
<span v-else-if="!like">{{ i18n.ts.notSet }}</span>
|
<span v-else-if="!like">{{ i18n.ts.notSet }}</span>
|
||||||
|
|
Loading…
Reference in a new issue