feat: unread message tracking with blue dot indicator
Add ContactThreadRead model to track when users last viewed each contact thread. Contacts with messages newer than the last read time show a blue dot in the sidebar. Opening a thread automatically marks it as read via markThreadRead mutation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -87,8 +87,11 @@ export type Contact = {
|
||||
avatar: Scalars['String']['output'];
|
||||
channels: Array<Scalars['String']['output']>;
|
||||
description: Scalars['String']['output'];
|
||||
hasUnread: Scalars['Boolean']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
lastContactAt: Scalars['String']['output'];
|
||||
lastMessageChannel: Scalars['String']['output'];
|
||||
lastMessageText: Scalars['String']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
@@ -220,6 +223,7 @@ export type Mutation = {
|
||||
logPilotNote: MutationResult;
|
||||
login: MutationResult;
|
||||
logout: MutationResult;
|
||||
markThreadRead: MutationResult;
|
||||
rollbackChangeSetItems: MutationResult;
|
||||
rollbackLatestChangeSet: MutationResult;
|
||||
selectChatConversation: MutationResult;
|
||||
@@ -277,6 +281,11 @@ export type MutationloginArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationmarkThreadReadArgs = {
|
||||
contactId: Scalars['ID']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationrollbackChangeSetItemsArgs = {
|
||||
changeSetId: Scalars['ID']['input'];
|
||||
itemIds: Array<Scalars['ID']['input']>;
|
||||
@@ -464,7 +473,7 @@ export type ContactInboxesQueryQuery = { __typename?: 'Query', contactInboxes: A
|
||||
export type ContactsQueryQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ContactsQueryQuery = { __typename?: 'Query', contacts: Array<{ __typename?: 'Contact', id: string, name: string, avatar: string, channels: Array<string>, lastContactAt: string, description: string }> };
|
||||
export type ContactsQueryQuery = { __typename?: 'Query', contacts: Array<{ __typename?: 'Contact', id: string, name: string, avatar: string, channels: Array<string>, lastContactAt: string, lastMessageText: string, lastMessageChannel: string, hasUnread: boolean, description: string }> };
|
||||
|
||||
export type CreateCalendarEventMutationMutationVariables = Exact<{
|
||||
input: CreateCalendarEventInput;
|
||||
@@ -544,6 +553,13 @@ export type LogoutMutationMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
export type LogoutMutationMutation = { __typename?: 'Mutation', logout: { __typename?: 'MutationResult', ok: boolean } };
|
||||
|
||||
export type MarkThreadReadMutationVariables = Exact<{
|
||||
contactId: Scalars['ID']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarkThreadReadMutation = { __typename?: 'Mutation', markThreadRead: { __typename?: 'MutationResult', ok: boolean } };
|
||||
|
||||
export type MeQueryQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
@@ -921,6 +937,9 @@ export const ContactsQueryDocument = gql`
|
||||
avatar
|
||||
channels
|
||||
lastContactAt
|
||||
lastMessageText
|
||||
lastMessageChannel
|
||||
hasUnread
|
||||
description
|
||||
}
|
||||
}
|
||||
@@ -1399,6 +1418,35 @@ export function useLogoutMutationMutation(options: VueApolloComposable.UseMutati
|
||||
return VueApolloComposable.useMutation<LogoutMutationMutation, LogoutMutationMutationVariables>(LogoutMutationDocument, options);
|
||||
}
|
||||
export type LogoutMutationMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<LogoutMutationMutation, LogoutMutationMutationVariables>;
|
||||
export const MarkThreadReadDocument = gql`
|
||||
mutation MarkThreadRead($contactId: ID!) {
|
||||
markThreadRead(contactId: $contactId) {
|
||||
ok
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useMarkThreadReadMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useMarkThreadReadMutation` within a Vue component and pass it any options that fit your needs.
|
||||
* When your component renders, `useMarkThreadReadMutation` returns an object that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - Several other properties: https://v4.apollo.vuejs.org/api/use-mutation.html#return
|
||||
*
|
||||
* @param options that will be passed into the mutation, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/mutation.html#options;
|
||||
*
|
||||
* @example
|
||||
* const { mutate, loading, error, onDone } = useMarkThreadReadMutation({
|
||||
* variables: {
|
||||
* contactId: // value for 'contactId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useMarkThreadReadMutation(options: VueApolloComposable.UseMutationOptions<MarkThreadReadMutation, MarkThreadReadMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<MarkThreadReadMutation, MarkThreadReadMutationVariables>> = {}) {
|
||||
return VueApolloComposable.useMutation<MarkThreadReadMutation, MarkThreadReadMutationVariables>(MarkThreadReadDocument, options);
|
||||
}
|
||||
export type MarkThreadReadMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<MarkThreadReadMutation, MarkThreadReadMutationVariables>;
|
||||
export const MeQueryDocument = gql`
|
||||
query MeQuery {
|
||||
me {
|
||||
|
||||
@@ -7,6 +7,7 @@ query ContactsQuery {
|
||||
lastContactAt
|
||||
lastMessageText
|
||||
lastMessageChannel
|
||||
hasUnread
|
||||
description
|
||||
}
|
||||
}
|
||||
|
||||
5
frontend/graphql/operations/mark-thread-read.graphql
Normal file
5
frontend/graphql/operations/mark-thread-read.graphql
Normal file
@@ -0,0 +1,5 @@
|
||||
mutation MarkThreadRead($contactId: ID!) {
|
||||
markThreadRead(contactId: $contactId) {
|
||||
ok
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ type Mutation {
|
||||
updateCommunicationTranscript(id: ID!, transcript: [String!]!): MutationWithIdResult!
|
||||
updateFeedDecision(id: ID!, decision: String!, decisionNote: String): MutationWithIdResult!
|
||||
setContactInboxHidden(inboxId: ID!, hidden: Boolean!): MutationResult!
|
||||
markThreadRead(contactId: ID!): MutationResult!
|
||||
}
|
||||
|
||||
type MutationResult {
|
||||
@@ -173,6 +174,7 @@ type Contact {
|
||||
lastContactAt: String!
|
||||
lastMessageText: String!
|
||||
lastMessageChannel: String!
|
||||
hasUnread: Boolean!
|
||||
description: String!
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user