mirror of
https://github.com/versia-pub/frontend.git
synced 2026-03-13 03:29:16 +01:00
feat: ✨ Create new user profile view, refine components, add dropdown to notes
This commit is contained in:
parent
a0d0737683
commit
a17df9fff8
21 changed files with 470 additions and 133 deletions
92
composables/AccountTimeline.ts
Normal file
92
composables/AccountTimeline.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import type { Mastodon } from "megalodon";
|
||||
import type { Status } from "~/types/mastodon/status";
|
||||
|
||||
export const useAccountTimeline = (
|
||||
client: Mastodon | null,
|
||||
id: string | null,
|
||||
options: MaybeRef<
|
||||
Partial<{
|
||||
limit?: number | undefined;
|
||||
max_id?: string | undefined;
|
||||
since_id?: string | undefined;
|
||||
min_id?: string | undefined;
|
||||
pinned?: boolean | undefined;
|
||||
exclude_replies?: boolean | undefined;
|
||||
exclude_reblogs?: boolean | undefined;
|
||||
only_media: boolean;
|
||||
}>
|
||||
>,
|
||||
): {
|
||||
timeline: Ref<Status[]>;
|
||||
loadNext: () => Promise<void>;
|
||||
loadPrev: () => Promise<void>;
|
||||
} => {
|
||||
if (!client || !id) {
|
||||
return {
|
||||
timeline: ref([]),
|
||||
loadNext: async () => {},
|
||||
loadPrev: async () => {},
|
||||
};
|
||||
}
|
||||
|
||||
const fetchedNotes = ref<Status[]>([]);
|
||||
const fetchedNoteIds = new Set<string>();
|
||||
let nextMaxId: string | undefined = undefined;
|
||||
let prevMinId: string | undefined = undefined;
|
||||
|
||||
const loadNext = async () => {
|
||||
const response = await client.getAccountStatuses(id, {
|
||||
only_media: false,
|
||||
...ref(options).value,
|
||||
max_id: nextMaxId,
|
||||
limit: useConfig().NOTES_PER_PAGE,
|
||||
});
|
||||
|
||||
const newNotes = response.data.filter(
|
||||
(note) => !fetchedNoteIds.has(note.id),
|
||||
);
|
||||
if (newNotes.length > 0) {
|
||||
fetchedNotes.value = [...fetchedNotes.value, ...newNotes];
|
||||
nextMaxId = newNotes[newNotes.length - 1].id;
|
||||
for (const note of newNotes) {
|
||||
fetchedNoteIds.add(note.id);
|
||||
}
|
||||
} else {
|
||||
nextMaxId = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const loadPrev = async () => {
|
||||
const response = await client.getAccountStatuses(id, {
|
||||
only_media: false,
|
||||
...ref(options).value,
|
||||
min_id: prevMinId,
|
||||
limit: useConfig().NOTES_PER_PAGE,
|
||||
});
|
||||
|
||||
const newNotes = response.data.filter(
|
||||
(note) => !fetchedNoteIds.has(note.id),
|
||||
);
|
||||
if (newNotes.length > 0) {
|
||||
fetchedNotes.value = [...newNotes, ...fetchedNotes.value];
|
||||
prevMinId = newNotes[0].id;
|
||||
for (const note of newNotes) {
|
||||
fetchedNoteIds.add(note.id);
|
||||
}
|
||||
} else {
|
||||
prevMinId = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => ref(options).value,
|
||||
async ({ max_id, min_id }) => {
|
||||
nextMaxId = max_id;
|
||||
prevMinId = min_id;
|
||||
await loadNext();
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
return { timeline: fetchedNotes, loadNext, loadPrev };
|
||||
};
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { renderToString } from "vue/server-renderer";
|
||||
import type { Account } from "~/types/mastodon/account";
|
||||
import type { Emoji } from "~/types/mastodon/emoji";
|
||||
import MentionComponent from "../components/social-elements/notes/mention.vue";
|
||||
import { renderToString } from "vue/server-renderer";
|
||||
|
||||
/**
|
||||
* Takes in an HTML string, parses emojis and returns a reactive object with the parsed content.
|
||||
|
|
@ -55,5 +55,24 @@ export const useParsedContent = async (
|
|||
|
||||
link.outerHTML = await renderToString(renderedMention);
|
||||
}
|
||||
|
||||
// Highlight code blocks
|
||||
const codeBlocks = contentHtml.querySelectorAll("pre code");
|
||||
for (const codeBlock of codeBlocks) {
|
||||
const code = codeBlock.textContent;
|
||||
if (!code) {
|
||||
continue;
|
||||
}
|
||||
const newCode = (await getShikiHighlighter()).highlight(code, {
|
||||
lang: codeBlock.getAttribute("class")?.replace("language-", ""),
|
||||
});
|
||||
|
||||
// Replace parent pre tag with highlighted code
|
||||
const parent = codeBlock.parentElement;
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
parent.outerHTML = newCode;
|
||||
}
|
||||
return ref(contentHtml.innerHTML);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue