// Fetch all users concurrently
return await Promise.all(users);
}
+
+export async function startWatchingBuild(uuid: string): Promise<undefined> {
+ await api.post(`/v1/builds/${uuid}/watchers`);
+}
+
+export async function stopWatchingBuild(uuid: string): Promise<undefined> {
+ await api.delete(`/v1/builds/${uuid}/watchers`);
+}
import { ref, onMounted } from "vue";
// Composables
+ import { useAuth } from "@/composables/auth";
import { useBuild } from "@/composables/builds";
// Fetch the build UUID
const loading = ref(true);
const error = ref<Error | null>(null);
+ const watching = ref(false);
// Fetch the build
- const { watchers, getWatchers } = useBuild(props.uuid);
+ const {
+ watchers,
+ getWatchers,
+ isWatching,
+ startWatching,
+ stopWatching
+ } = useBuild(props.uuid);
+
+ // Fetch authentication
+ const { user, isLoggedIn } = useAuth();
onMounted(async () => {
try {
} finally {
loading.value = false;
}
+
+ // Is the current user watching?
+ if (user.value)
+ watching.value = await isWatching(user.value);
});
+
+ const loadingAction = ref(false);
+
+ async function watchBuild() {
+ loadingAction.value = true;
+
+ try {
+ await startWatching();
+ } finally {
+ loadingAction.value = false;
+ }
+
+ // We are now watching
+ watching.value = true;
+ }
+
+ async function unwatchBuild() {
+ loadingAction.value = true;
+
+ try {
+ await stopWatching();
+ } finally {
+ loadingAction.value = false;
+ }
+
+ // We are no longer watching
+ watching.value = false;
+ }
</script>
<template>
class="level-item" v-for="watcher in watchers" :key="watcher.name">
<Avatar :user="watcher" size="32" is-rounded />
</RouterLink>
+
+ <!-- Show controls if the user is logged in -->
+ <div class="level-item" v-if="isLoggedIn">
+ <Button v-if="watching" :loading="loadingAction" is-small is-danger
+ @click="unwatchBuild">
+ Unwatch this build
+ </Button>
+
+ <Button v-else is-small :loading="loadingAction" is-success
+ @click="watchBuild">
+ Watch this build
+ </Button>
+ </div>
</div>
</div>
</Loader>
fetchBuild,
fetchBuildBugs,
fetchBuildWatchers,
+ startWatchingBuild,
+ stopWatchingBuild,
} from "@/api/builds";
import type { User } from "@/api/users";
+// Composables
+import { useAuth } from "@/composables/auth";
+
export function useBuild(uuid: string) {
const build = ref<Build>();
// Cache all watchers
const watchers = ref<User[]>();
+ // Fetch authentication
+ const { user, isLoggedIn } = useAuth();
+
// Fetch the build
async function loadBuild() {
build.value = await fetchBuild(uuid);
return watchers.value;
}
+ // Returns true if the given user is watching this build
+ async function isWatching(user: User): Promise<boolean> {
+ // Fetch all watchers
+ const watchers = await getWatchers();
+
+ // Check if the user is on the list
+ return watchers.find(
+ (watcher) => watcher.name === user.name
+ ) ? true : false;
+ }
+
+ async function startWatching(): Promise<undefined> {
+ // Start watching the build
+ await startWatchingBuild(uuid);
+
+ // Add the user to the list of watchers
+ if (user.value)
+ watchers.value?.push(user.value);
+ }
+
+ async function stopWatching(): Promise<undefined> {
+ await stopWatchingBuild(uuid);
+
+ // Remove the watcher
+ watchers.value = watchers.value?.filter(
+ (watcher) => watcher.name !== user.value?.name
+ );
+ }
+
return {
build,
watchers,
loadBuild,
getBugs,
getWatchers,
+ isWatching,
+ startWatching,
+ stopWatching,
};
}