Verified Commit 22c30ec9 authored by Marek Veselý's avatar Marek Veselý
Browse files

refactor: use localstorage for emailThread.archived

parent d405c018
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
import { makeExecutableSchema } from '@graphql-tools/schema'
import type { ExecutionResult } from '@graphql-tools/utils'
import { Keys } from '@inject/shared'
import emailThreadArchivedQL from '../../schemas/emailThreadArchived.graphql'
import { executeRead, executeWrite } from '../utils'
import type { Resolvers } from './emailThreadArchivedType'
import type { Context, SubschemaConfig, SubschemaResolverType } from './typing'

@@ -11,27 +10,34 @@ const schema = makeExecutableSchema<Context>({
  typeDefs: [emailThreadArchivedQL],
  resolvers: {
    Query: {
      getArchived: async (_, { emailThreadId }, { exerciseId }) => {
        const { data } = (await executeRead({
          exerciseId,
          key: 'emailThreadArchive',
          subkey: [emailThreadId],
        })) as ExecutionResult<{ readValue: string | null }>
      getArchived: async (_, { emailThreadId }) => {
        const key = Keys.getEmailThreadArchivedKey(emailThreadId)
        const localStorageValue = localStorage.getItem(key)
        // if no local storage value is present, the email thread is considered
        // not archived
        const archived = (() => {
          if (localStorageValue === null) {
            const archived = false
            localStorage.setItem(key, JSON.stringify(archived))
            return archived
          }
          return JSON.parse(localStorageValue)
        })()
        return {
          archived: JSON.parse(data?.readValue || 'false'),
          __typename: 'EmailThreadType',
          id: emailThreadId,
          archived,
        }
      },
    },
    Mutation: {
      setArchived: (_, { emailThreadId, state }, { exerciseId }) => {
        executeWrite({
          exerciseId,
          key: 'emailThreadArchive',
          value: JSON.stringify(state),
          subkey: [emailThreadId],
        })
      setArchived: (_, { emailThreadId, state }) => {
        localStorage.setItem(
          Keys.getEmailThreadArchivedKey(emailThreadId),
          state.toString()
        )
        return {
          __typename: 'EmailThreadType',
          id: emailThreadId,
          archived: state,
        }
+98 −101
Original line number Diff line number Diff line
import { KeysV2 as Keys } from '@inject/shared'
import type { ResultOf, VariablesOf } from '../graphql'
import { graphql } from '../graphql'
import { httpExecutor } from './subschemas/remoteSchema'

const mutation = graphql(`
  mutation mutateKV($exerciseId: ID!, $key: String!, $value: String!) {
    writeValue(exerciseId: $exerciseId, key: $key, value: $value) {
      newValue
    }
  }
`)
// const mutation = graphql(`
//   mutation mutateKV($exerciseId: ID!, $key: String!, $value: String!) {
//     writeValue(exerciseId: $exerciseId, key: $key, value: $value) {
//       newValue
//     }
//   }
// `)

const query = graphql(`
  query readKV($exerciseId: ID!, $key: String!) {
    readValue(exerciseId: $exerciseId, key: $key)
  }
`)
// const query = graphql(`
//   query readKV($exerciseId: ID!, $key: String!) {
//     readValue(exerciseId: $exerciseId, key: $key)
//   }
// `)

type KeysV2 = typeof Keys

@@ -72,94 +69,94 @@ export function processKvStorageEvent<K extends KeyType>(
}

// TODO: create temporary cache for noting changed variables (to prevent double re-rendering)
export function executeWrite<K extends KeyType>({
  exerciseId,
  key,
  value,
  subkey,
}: {
  exerciseId: string
  value: string
} & (
  | {
      key: K & StringKeyType
      subkey?: never
    }
  | {
      key: K & FunctionKeyType
      subkey: KeyArgs<K>
    }
)) {
  if (typeof Keys[key][0] === 'string') {
    return httpExecutor<
      ResultOf<typeof mutation>,
      VariablesOf<typeof mutation>
    >({
      document: mutation,
      variables: {
        exerciseId,
        key: Keys[key][0],
        value,
      },
    })
  } else if (typeof Keys[key][0] === 'function' && subkey !== undefined) {
    const fn = Keys[key][0]
    //@ts-ignore
    const fullkey = fn(...subkey) // there is a type error expected, ignore it
    return httpExecutor<
      ResultOf<typeof mutation>,
      VariablesOf<typeof mutation>
    >({
      document: mutation,
      variables: {
        exerciseId,
        key: fullkey,
        value,
      },
    })
  }
  throw Error('Unknown')
}
// export function executeWrite<K extends KeyType>({
//   exerciseId,
//   key,
//   value,
//   subkey,
// }: {
//   exerciseId: string
//   value: string
// } & (
//   | {
//       key: K & StringKeyType
//       subkey?: never
//     }
//   | {
//       key: K & FunctionKeyType
//       subkey: KeyArgs<K>
//     }
// )) {
//   if (typeof Keys[key][0] === 'string') {
//     return httpExecutor<
//       ResultOf<typeof mutation>,
//       VariablesOf<typeof mutation>
//     >({
//       document: mutation,
//       variables: {
//         exerciseId,
//         key: Keys[key][0],
//         value,
//       },
//     })
//   } else if (typeof Keys[key][0] === 'function' && subkey !== undefined) {
//     const fn = Keys[key][0]
//     //@ts-ignore
//     const fullkey = fn(...subkey) // there is a type error expected, ignore it
//     return httpExecutor<
//       ResultOf<typeof mutation>,
//       VariablesOf<typeof mutation>
//     >({
//       document: mutation,
//       variables: {
//         exerciseId,
//         key: fullkey,
//         value,
//       },
//     })
//   }
//   throw Error('Unknown')
// }

// TODO: establish hot-cache for already existing fields with ensurance of TTL
export function executeRead<K extends KeyType>({
  exerciseId,
  key,
  subkey,
}: {
  exerciseId: string
} & (
  | {
      key: K & StringKeyType
      subkey?: never
    }
  | {
      key: K & FunctionKeyType
      subkey: KeyArgs<K>
    }
)) {
  if (typeof Keys[key][0] === 'string') {
    return httpExecutor<ResultOf<typeof query>, VariablesOf<typeof query>>({
      document: query,
      variables: {
        exerciseId,
        key: Keys[key][0],
      },
    })
  } else if (typeof Keys[key][0] === 'function' && subkey !== undefined) {
    const fn = Keys[key][0]
    //@ts-ignore
    const fullkey = fn(...subkey) // there is a type error expected, ignore it
    return httpExecutor<ResultOf<typeof query>, VariablesOf<typeof query>>({
      document: query,
      variables: {
        exerciseId,
        key: fullkey,
      },
    })
  }
  throw Error('Unknown')
}
// export function executeRead<K extends KeyType>({
//   exerciseId,
//   key,
//   subkey,
// }: {
//   exerciseId: string
// } & (
//   | {
//       key: K & StringKeyType
//       subkey?: never
//     }
//   | {
//       key: K & FunctionKeyType
//       subkey: KeyArgs<K>
//     }
// )) {
//   if (typeof Keys[key][0] === 'string') {
//     return httpExecutor<ResultOf<typeof query>, VariablesOf<typeof query>>({
//       document: query,
//       variables: {
//         exerciseId,
//         key: Keys[key][0],
//       },
//     })
//   } else if (typeof Keys[key][0] === 'function' && subkey !== undefined) {
//     const fn = Keys[key][0]
//     //@ts-ignore
//     const fullkey = fn(...subkey) // there is a type error expected, ignore it
//     return httpExecutor<ResultOf<typeof query>, VariablesOf<typeof query>>({
//       document: query,
//       variables: {
//         exerciseId,
//         key: fullkey,
//       },
//     })
//   }
//   throw Error('Unknown')
// }

export function processKVSubscription({
  exerciseId,
+1 −0
Original line number Diff line number Diff line
@@ -66,5 +66,6 @@ export const Keys = {
    `analyst-room-view-config:${exerciseId}`,
  getAnalystRoomViewGridConfigKey: (exerciseId: string) =>
    `analyst-room-view-grid-config:${exerciseId}`,
  getEmailThreadArchivedKey: (id: string) => `email-thread-archived:${id}`,
  USERCOLUMNS: 'user-columns',
}