+
-
+
diff --git a/src/components/status/VulStatusButtons.vue b/src/components/status/VulStatusButtons.vue
index 731b54a..7bca37e 100644
--- a/src/components/status/VulStatusButtons.vue
+++ b/src/components/status/VulStatusButtons.vue
@@ -1,26 +1,33 @@
-
-
+
+
-
- {{ status.replies_count }}
+ {{ status.replies_count }}
-
- {{ status.reblogs_count }}
+ {{ status.reblogs_count }}
-
-
- {{ status.favourites_count }}
+ {{ status.favourites_count }}
-
diff --git a/src/components/status/VulStatusContent.vue b/src/components/status/VulStatusContent.vue
index 2d7ffa5..dd61f11 100644
--- a/src/components/status/VulStatusContent.vue
+++ b/src/components/status/VulStatusContent.vue
@@ -13,7 +13,7 @@ const isCollapsed = ref(!!status.spoiler_text);
-
+
(isCollapsed = !isCollapsed)">
diff --git a/src/components/status/VulStatusInfo.vue b/src/components/status/VulStatusInfo.vue
index 5a4ce32..ecfd4be 100644
--- a/src/components/status/VulStatusInfo.vue
+++ b/src/components/status/VulStatusInfo.vue
@@ -34,7 +34,7 @@ const statusScopeIcon = ({ visibility }: Activity) => {
-
+
-
- {dom}
-
- {elements}
- >
- );
+ return <>{elements}>;
}
/** Create a custom emoji element and return its string representation.
@@ -57,8 +49,6 @@ function parseElement(elem: ChildNode, emoji: CustomEmoji[], tags: Tag[], mentio
// text node, just add it to the output unmodified
out.push(<>{elem.data}>);
} else if (elem instanceof Element) {
- console.log(elem.name, elem.attribs);
-
switch (elem.name) {
case "x-emoji":
// Turn into a VulEmoji component
@@ -70,8 +60,8 @@ function parseElement(elem: ChildNode, emoji: CustomEmoji[], tags: Tag[], mentio
if ("class" in elem.attribs && elem.attribs.class === "h-card") {
// if so, parse that mention and add a component for it
if (elem.children.length === 0) throw "Invalid mention, span with type h-card doesn't have child";
- const userId = (elem.children[0] as Element).attribs["data-user"];
- const user = mentions.find((m) => m.id === userId);
+ const userUrl = (elem.children[0] as Element).attribs["href"];
+ const user = mentions.find((m) => m.url === userUrl);
if (!user) throw "Invalid mention, user is not found in Status.mentions";
// add the mention component
out.push();
diff --git a/src/components/status/content/VulEmoji.vue b/src/components/status/content/VulEmoji.vue
index bd63a16..0331a5e 100644
--- a/src/components/status/content/VulEmoji.vue
+++ b/src/components/status/content/VulEmoji.vue
@@ -11,6 +11,6 @@ defineProps<{ emoji: CustomEmoji }>();
diff --git a/src/components/status_tree/StatusTree.vue b/src/components/status_tree/StatusTree.vue
new file mode 100644
index 0000000..2ba16b1
--- /dev/null
+++ b/src/components/status_tree/StatusTree.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/api/entities/activity.ts b/src/lib/api/entities/activity.ts
index c76ddef..752fce7 100644
--- a/src/lib/api/entities/activity.ts
+++ b/src/lib/api/entities/activity.ts
@@ -19,6 +19,11 @@ export default interface Activity {
replies_count: number;
}
+export interface ActivityContext {
+ ancestors: Activity[];
+ descendants: Activity[];
+}
+
export interface ActivityAkkoma {
source: ActivityAkkomaSource;
}
diff --git a/src/main.ts b/src/main.ts
index 93f686a..6311a7d 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,4 +1,5 @@
import "./assets/style.css";
+import "./assets/mfm.scss";
import { createApp } from "vue";
import { createPinia } from "pinia";
diff --git a/src/views/StatusView.vue b/src/views/StatusView.vue
index da3e6fc..2300aeb 100644
--- a/src/views/StatusView.vue
+++ b/src/views/StatusView.vue
@@ -3,18 +3,23 @@ import { ref, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import useSWRV from "swrv";
import type Activity from "@/lib/api/entities/activity";
+import type { ActivityContext } from "@/lib/api/entities/activity";
import apiFetch from "@/lib/api-fetch";
+import watchTitle from "@/lib/title";
import { FwbSpinner } from "flowbite-vue";
-import VulStatus from "@/components/status/VulStatus.vue";
-import watchTitle from "@/lib/title";
+import StatusTree from "@/components/status_tree/StatusTree.vue";
const router = useRouter();
const route = useRoute();
const username = ref(route.params.username);
const statusId = ref(route.params.statusId);
-const { data, error } = useSWRV(() => `/api/v1/statuses/${statusId.value}`, apiFetch);
+const { data: status, error: statusError } = useSWRV(() => `/api/v1/statuses/${statusId.value}`, apiFetch);
+const { data: context, error: contextError } = useSWRV(
+ () => `/api/v1/statuses/${statusId.value}/context`,
+ apiFetch,
+);
// update username/status ID whenever we navigate to another page
watch(
@@ -27,9 +32,9 @@ watch(
// always have the correct username in the URL
watch(
- () => ({ activity: data.value, username: route.params.username }),
- ({ activity, username }) => {
- if (activity && activity.account.acct !== username) {
+ () => ({ activity: status.value, username: route.params.username, statusId: statusId.value }),
+ ({ activity, username, statusId }) => {
+ if (activity && activity.id === statusId && activity.account.acct !== username) {
router.push({
name: "user-status",
params: { username: activity.account.acct, statusId: activity.id },
@@ -43,11 +48,12 @@ watchTitle((activity) => {
const user = activity.account.display_name;
let text = activity.spoiler_text || activity.content || "N/A";
return `${user}: "${text.length > 29 ? text.slice(0, 30) + "…" : text}"`;
-}, data);
+}, status);
+
- Failed to load: {{ error }}
-
-
+ Failed to load: {{ statusError || contextError }}
+
+