diff --git a/components/notes/header.vue b/components/notes/header.vue
index 4d43e02..701c433 100644
--- a/components/notes/header.vue
+++ b/components/notes/header.vue
@@ -27,9 +27,9 @@
-
+
-
+
@@ -44,7 +44,7 @@ import type {
import { AtSign, Globe, Lock, LockOpen } from "lucide-vue-next";
import CopyableText from "./copyable-text.vue";
-const { acct, createdAt, url } = defineProps<{
+const { acct, createdAt, url, noteUrl } = defineProps<{
avatar: string;
cornerAvatar?: string;
acct: string;
@@ -52,6 +52,7 @@ const { acct, createdAt, url } = defineProps<{
emojis: Emoji[];
visibility: StatusVisibility;
url: string;
+ noteUrl: string;
createdAt: Date;
smallLayout?: boolean;
}>();
@@ -59,6 +60,7 @@ const { acct, createdAt, url } = defineProps<{
const [username, instance] = acct.split("@");
const digitRegex = /\d/;
const urlAsPath = new URL(url).pathname;
+const noteUrlAsPath = new URL(noteUrl).pathname;
const timeAgo = useTimeAgo(createdAt, {
messages: {
justNow: "now",
diff --git a/components/notes/note.vue b/components/notes/note.vue
index a6134bb..ebd8968 100644
--- a/components/notes/note.vue
+++ b/components/notes/note.vue
@@ -4,16 +4,23 @@
-
+
+ :api-note-string="JSON.stringify(note, null, 4)" :reblog-count="noteToUse.reblogs_count"
+ :remote-url="noteToUse.url" :is-remote="isRemote" :author-id="noteToUse.account.id"
+ @edit="useEvent('composer:edit', note)" @reply="useEvent('composer:reply', note)"
+ @quote="useEvent('composer:quote', note)" @delete="useEvent('note:delete', note)"
+ :note-id="noteToUse.id" :liked="noteToUse.favourited ?? false"
+ :reblogged="noteToUse.reblogged ?? false" />
diff --git a/components/social-elements/users/SmallCard.vue b/components/social-elements/users/SmallCard.vue
deleted file mode 100644
index 5ee65f6..0000000
--- a/components/social-elements/users/SmallCard.vue
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{
- account?.display_name }}
-
-
-
-
-
- @{{
- account?.acct
- }}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/composables/NoteData.ts b/composables/NoteData.ts
deleted file mode 100644
index 49295b6..0000000
--- a/composables/NoteData.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import type { Client } from "@versia/client";
-import type { Status } from "@versia/client/types";
-import { SettingIds, type Settings } from "~/settings";
-
-export const useNoteData = (
- noteProp: MaybeRef,
- client: Ref,
- settings: MaybeRef,
-) => {
- const isReply = computed(() => !!toValue(noteProp)?.in_reply_to_id);
- const isQuote = computed(() => !!toValue(noteProp)?.quote);
- const isReblog = computed(
- () => !isQuote.value && !!toValue(noteProp)?.reblog,
- );
- const renderedNote = computed(() =>
- isReblog.value
- ? (toValue(noteProp)?.reblog ?? toValue(noteProp))
- : toValue(noteProp),
- );
- const showContentWarning = useSetting(SettingIds.ShowContentWarning);
- const shouldHide = computed(
- () =>
- (renderedNote.value?.sensitive ||
- !!renderedNote.value?.spoiler_text) &&
- (showContentWarning.value.value as boolean),
- );
- const mentions = useResolveMentions(
- computed(() => renderedNote.value?.mentions ?? []),
- client.value,
- );
- const content = useParsedContent(
- computed(() => renderedNote.value?.content ?? ""),
- computed(() => renderedNote.value?.emojis ?? []),
- mentions,
- settings,
- );
- const loaded = computed(() => content.value !== null);
-
- const reblogDisplayName = useParsedContent(
- toValue(noteProp)?.account.display_name ?? "",
- toValue(noteProp)?.account.emojis ?? [],
- undefined,
- settings,
- );
- const reblog = computed(() =>
- isReblog.value && toValue(noteProp) && !isQuote.value
- ? {
- avatar: toValue(noteProp)?.account.avatar,
- acct: toValue(noteProp)?.account.acct,
- }
- : null,
- );
-
- const url = computed(() =>
- new URL(
- `/@${renderedNote.value?.account.acct}/${renderedNote.value?.id}`,
- window.location.origin,
- ).toString(),
- );
-
- const remove = async () => {
- const result = await client.value.deleteStatus(
- renderedNote.value?.id ?? "",
- );
-
- if (result?.data) {
- useEvent("note:delete", result.data);
- }
- };
-
- return {
- loaded,
- note: renderedNote,
- content,
- isQuote,
- reblog,
- reblogDisplayName,
- shouldHide,
- isReply,
- url,
- remove,
- };
-};
diff --git a/composables/ParsedContent.ts b/composables/ParsedContent.ts
deleted file mode 100644
index 876ba77..0000000
--- a/composables/ParsedContent.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-import type { Account, Emoji } from "@versia/client/types";
-import { SettingIds, type Settings } from "~/settings";
-
-const emojisRegex =
- /\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?(\u200D(\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?))*/gu;
-const incorrectEmojisRegex = /^[#*0-9©®]$/;
-
-/**
- * Takes in an HTML string, parses emojis and returns a reactive object with the parsed content.
- * @param content String of HTML content to parse
- * @param emojis Array of emojis to parse
- * @returns Reactive object with the parsed content
- */
-export const useParsedContent = (
- content: MaybeRef,
- emojis: MaybeRef,
- mentions: MaybeRef = ref([]),
- settings: MaybeRef = ref(null),
-): Ref => {
- const result = ref(null as string | null);
-
- watch(
- isRef(content)
- ? isRef(emojis)
- ? [content, mentions, emojis]
- : [content, mentions]
- : mentions,
- async () => {
- const contentHtml = document.createElement("div");
- contentHtml.innerHTML = toValue(content);
-
- const shouldRenderEmoji =
- toValue(settings)?.[SettingIds.CustomEmojis].value;
- const emojiFont = toValue(settings)?.[SettingIds.EmojiTheme].value;
-
- // Replace emoji shortcodes with images
- if (shouldRenderEmoji) {
- contentHtml.innerHTML = contentHtml.innerHTML.replace(
- /:([a-zA-Z0-9_-]+):/g,
- (match, emoji) => {
- const emojiData = toValue(emojis).find(
- (e) => e.shortcode === emoji,
- );
- if (!emojiData) {
- return match;
- }
- const image = document.createElement("img");
- image.src = emojiData.url;
- image.alt = `:${emoji}:`;
- image.title = emojiData.shortcode;
- image.className =
- "h-[1.6em] mt-[-0.2ex] mx-1 mb-[0.2ex] align-middle inline not-prose hover:scale-110 transition-transform duration-75 ease-in-out";
- return image.outerHTML;
- },
- );
- }
-
- if (emojiFont !== "native") {
- contentHtml.innerHTML = contentHtml.innerHTML.replace(
- emojisRegex,
- (match) => {
- if (incorrectEmojisRegex.test(match)) {
- return match;
- }
-
- return `
`;
- },
- );
- }
-
- result.value = contentHtml.innerHTML;
- },
- { immediate: true },
- );
-
- return result;
-};
-
-export const useParsedAccount = (
- account: MaybeRef,
- settings: MaybeRef,
-) => {
- const displayName = computed(
- () =>
- toValue(account)?.display_name ?? toValue(account)?.username ?? "",
- );
- const note = computed(() => toValue(account)?.note ?? "");
- const fields = computed(() => toValue(account)?.fields ?? []);
- const emojis = computed(() => toValue(account)?.emojis ?? []);
-
- const parsedDisplayName = useParsedContent(
- displayName,
- emojis,
- undefined,
- settings,
- );
-
- const parsedNote = useParsedContent(note, emojis, undefined, settings);
-
- const parsedFields = computed(() =>
- fields.value.map((field) => ({
- ...field,
- name: useParsedContent(field.name, emojis, undefined, settings)
- .value,
- value: useParsedContent(field.value, emojis, undefined, settings)
- .value,
- })),
- );
-
- return {
- display_name: parsedDisplayName,
- note: parsedNote,
- fields: parsedFields,
- };
-};
diff --git a/pages/[username]/[uuid].vue b/pages/[username]/[uuid].vue
index 340bad7..a2ef3f7 100644
--- a/pages/[username]/[uuid].vue
+++ b/pages/[username]/[uuid].vue
@@ -1,17 +1,17 @@
-