From ae466b879cd09a9d04ffab0469ee991c7d90ce8e Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Tue, 12 Dec 2023 11:39:27 +0100
Subject: [PATCH] fix(front-end): fix current actor not being set on first
 access when relogging

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 src/App.vue                     |  9 ++++++--
 src/composition/apollo/actor.ts |  8 ++++++-
 src/utils/identity.ts           | 37 +++++++++++----------------------
 src/views/User/LoginView.vue    | 11 ++++++++--
 4 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/src/App.vue b/src/App.vue
index efdc54941..80d16f49f 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -70,6 +70,7 @@ import { CONFIG } from "@/graphql/config";
 import { IConfig } from "@/types/config.model";
 import { useRouter } from "vue-router";
 import RouteName from "@/router/name";
+import { useLazyCurrentUserIdentities } from "./composition/apollo/actor";
 
 const { result: configResult } = useQuery<{ config: IConfig }>(
   CONFIG,
@@ -138,11 +139,15 @@ interval.value = window.setInterval(async () => {
   }
 }, 60000) as unknown as number;
 
+const { load: loadIdentities } = useLazyCurrentUserIdentities();
+
 onBeforeMount(async () => {
   console.debug("Before mount App");
   if (initializeCurrentUser()) {
     try {
-      await initializeCurrentActor();
+      const result = await loadIdentities();
+      if (!result) return;
+      await initializeCurrentActor(result.loggedUser.actors);
     } catch (err) {
       if (err instanceof NoIdentitiesException) {
         await router.push({
@@ -223,7 +228,7 @@ const initializeCurrentUser = () => {
     console.debug("Initialized current user", userData);
     return true;
   }
-  console.debug("Failed to initialize current user");
+  console.debug("We don't seem to have a currently logged-in user");
   return false;
 };
 
diff --git a/src/composition/apollo/actor.ts b/src/composition/apollo/actor.ts
index 3d654c4e3..5e2e8a922 100644
--- a/src/composition/apollo/actor.ts
+++ b/src/composition/apollo/actor.ts
@@ -6,7 +6,7 @@ import {
 } from "@/graphql/actor";
 import { IPerson } from "@/types/actor";
 import { ICurrentUser } from "@/types/current-user.model";
-import { useQuery } from "@vue/apollo-composable";
+import { useLazyQuery, useQuery } from "@vue/apollo-composable";
 import { computed, Ref, unref } from "vue";
 import { useCurrentUserClient } from "./user";
 
@@ -22,6 +22,12 @@ export function useCurrentActorClient() {
   return { currentActor, error, loading };
 }
 
+export function useLazyCurrentUserIdentities() {
+  return useLazyQuery<{
+    loggedUser: Pick<ICurrentUser, "actors">;
+  }>(IDENTITIES);
+}
+
 export function useCurrentUserIdentities() {
   const { currentUser } = useCurrentUserClient();
 
diff --git a/src/utils/identity.ts b/src/utils/identity.ts
index 6e595f5e4..665e6d070 100644
--- a/src/utils/identity.ts
+++ b/src/utils/identity.ts
@@ -1,14 +1,8 @@
 import { AUTH_USER_ACTOR_ID } from "@/constants";
-import { UPDATE_CURRENT_ACTOR_CLIENT, IDENTITIES } from "@/graphql/actor";
+import { UPDATE_CURRENT_ACTOR_CLIENT } from "@/graphql/actor";
 import { IPerson } from "@/types/actor";
-import { ICurrentUser } from "@/types/current-user.model";
 import { apolloClient } from "@/vue-apollo";
-import {
-  provideApolloClient,
-  useLazyQuery,
-  useMutation,
-} from "@vue/apollo-composable";
-import { computed } from "vue";
+import { provideApolloClient, useMutation } from "@vue/apollo-composable";
 
 export class NoIdentitiesException extends Error {}
 
@@ -38,38 +32,31 @@ export async function changeIdentity(identity: IPerson): Promise<void> {
   });
 }
 
-const { load: loadIdentities } = provideApolloClient(apolloClient)(() =>
-  useLazyQuery<{ loggedUser: Pick<ICurrentUser, "actors"> }>(IDENTITIES)
-);
-
 /**
  * We fetch from localStorage the latest actor ID used,
  * then fetch the current identities to set in cache
  * the current identity used
  */
-export async function initializeCurrentActor(): Promise<void> {
+export async function initializeCurrentActor(
+  identities: IPerson[] | undefined
+): Promise<void> {
   const actorId = localStorage.getItem(AUTH_USER_ACTOR_ID);
   console.debug("Initializing current actor", actorId);
 
   try {
-    const result = await loadIdentities();
-    if (!result) return;
+    if (!identities) {
+      console.debug("Failed to load user's identities", identities);
+      return;
+    }
 
-    console.debug("got identities", result);
-    const identities = computed(() => result.loggedUser?.actors);
-    console.debug(
-      "initializing current actor based on identities",
-      identities.value
-    );
-
-    if (identities.value && identities.value.length < 1) {
+    if (identities && identities.length < 1) {
       console.warn("Logged user has no identities!");
       throw new NoIdentitiesException();
     }
     const activeIdentity =
-      (identities.value || []).find(
+      (identities || []).find(
         (identity: IPerson | undefined) => identity?.id === actorId
-      ) || ((identities.value || [])[0] as IPerson);
+      ) || ((identities || [])[0] as IPerson);
 
     if (activeIdentity) {
       await changeIdentity(activeIdentity);
diff --git a/src/views/User/LoginView.vue b/src/views/User/LoginView.vue
index cfd815a19..f1b1320d0 100644
--- a/src/views/User/LoginView.vue
+++ b/src/views/User/LoginView.vue
@@ -143,6 +143,7 @@ import { LoginError, LoginErrorCode } from "@/types/enums";
 import { useCurrentUserClient } from "@/composition/apollo/user";
 import { useHead } from "@unhead/vue";
 import { enumTransformer, useRouteQuery } from "vue-use-route-query";
+import { useLazyCurrentUserIdentities } from "@/composition/apollo/actor";
 
 const { t } = useI18n({ useScope: "global" });
 const router = useRouter();
@@ -235,12 +236,17 @@ const loginAction = (e: Event) => {
   });
 };
 
+const { load: loadIdentities } = useLazyCurrentUserIdentities();
+
 const { onDone: onCurrentUserMutationDone, mutate: updateCurrentUserMutation } =
   useMutation(UPDATE_CURRENT_USER_CLIENT);
 
 onCurrentUserMutationDone(async () => {
+  console.debug("Current user mutation done, now setuping actors…");
   try {
-    await initializeCurrentActor();
+    const result = await loadIdentities();
+    if (!result) return;
+    await initializeCurrentActor(result.loggedUser.actors);
   } catch (err: any) {
     if (err instanceof NoIdentitiesException && currentUser.value) {
       await router.push({
@@ -257,6 +263,7 @@ onCurrentUserMutationDone(async () => {
 });
 
 const setupClientUserAndActors = async (login: ILogin): Promise<void> => {
+  console.debug("Setuping client user and actors");
   updateCurrentUserMutation({
     id: login.user.id,
     email: credentials.email,
@@ -298,7 +305,7 @@ onMounted(() => {
   if (currentUser.value?.isLoggedIn) {
     console.debug(
       "Current user is already logged-in, redirecting to Homepage",
-      currentUser
+      currentUser.value
     );
     router.push("/");
   }