1try{let e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="b2d0610d-486e-4b46-8a21-11eb34bf64cd",e._sentryDebugIdIdentifier="sentry-dbid-b2d0610d-486e-4b46-8a21-11eb34bf64cd")}catch(e){}"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9210],{49210:(e,t,a)=>{a.d(t,{ReadStatusService:()=>r});var s=a(98132);class n{async upsertReadPosition(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;try{let{error:s}=await this.supabase.from("team_chat_read_status").upsert({channel_id:e.channelId,member_id:e.memberId,context_type:e.parentMessageId?"thread":"channel",context_id:e.parentMessageId||e.channelId,last_read_message_id:e.lastReadMessageId,updated_at:new Date().toISOString()},{onConflict:"member_id,context_type,context_id"});if(s){var a;if(console.error("[ReadStatusRepository] Upsert error:",{error:s,errorCode:s.code,errorMessage:s.message,position:e}
1),"42501"===s.code||(null==(a=s.message)?void 0:a.includes("406"))){let{data:{user:t}}=await this.supabase.auth.getUser(),{data:a}=await this.supabase.from("workspace_members").select("id, user_id").eq("id",e.memberId).single();console.error("[ReadStatusRepository] RLS check failed:",{currentUserId:null==t?void 0:t.id,memberId:e.memberId,memberExists:!!a,memberUserId:null==a?void 0:a.user_id,isOwner:(null==a?void 0:a.user_id)===(null==t?void 0:t.id)})}if(t<3&&("40001"===s.code||"PGRST301"===s.code))return console.warn("[ReadStatusRepository] Retrying upsert (attempt ".concat(t+1,")...")),await new Promise(e=>setTimeout(e,100*Math.pow(2,t))),this.upsertReadPosition(e,t+1);throw s}}catch(e){throw console.error("[ReadStatusRepository] Failed to upsert read position:",e),e}}async getReadPosition(e,t,a){await this.supabase.auth.getUser(),await this.supabase.from("workspace_members").select("id, user_id").eq("id",e).single();let s=a?"thread":"channel",n=a||t,{data:r,error:d}=await this.supabase.from("team_chat_read_status").select("*").eq("member_id",e).eq("context_type",s).eq("context_id",n).single();if(d){var i;if("PGRST116"===d.code)return null;if(console.error("[ReadStatusRepository] Failed to get read position:",d),console.error("[ReadStatusRepository] Query details:",{table:"team_chat_read_status",filters:{member_id:e,context_type:s,context_id:n},errorCode:d.code,errorMessage:d.message,errorHint:d.hint,errorDetails:d.details}),"42501"===d.code||(null==(i=d.message)?void 0:i.includes("406")))return console.warn("[ReadStatusRepository] RLS policy denied access, treating as new read status"),null;throw d}return r?{id:r.id,memberId:r.member_id,channelId:r.channel_id,parentMessageId:"thread"===r.context_type?r.context_id:null,lastReadMessageId:r.last_read_message_id||"",lastReadAt:r.updated_at||"1970-01-01T00:00:00Z",contextType:r.context_type}:null}async getUnreadMessageCount(e,t,a){if("threads"===a)return this.getThreadUnreadCount(e,t);let s="1970-01-01T00:00:00Z";try{let a=await this.getReadPosition(e,t);(null==a?void 0:a.lastReadAt)&&(s=a.lastReadAt)}catch(e){console.warn("[ReadStatusRepository] Failed to get read position for unread count, using default:",e)}let n=this.supabase.from("team_chat_messages").select("*",{count:"exact",head:!0}).eq("channel_id",t).gt("created_at",s).neq("sender_member_id",e).is("deleted_at",null);"channel"===a&&(n=n.is("parent_message_id",null));let{count:r,error:d}=await n;if(d)throw console.error("[ReadStatusRepository] Failed to get unread count:",d),d;return r||0}async getThreadUnreadCount(e,t){let a="1970-01-01T00:00:00Z";try{let s=await this.getReadPosition(e,t);(null==s?void 0:s.lastReadAt)&&(a=s.lastReadAt)}catch(e){console.warn("[ReadStatusRepository] Failed to get channel read position for thread count, using default:",e)}let{data:s,error:n}=await this.supabase.from("team_chat_messages").select("id, parent_message_id, created_at").eq("channel_id",t).not("parent_message_id","is",null).neq("sender_member_id",e).is("deleted_at",null).order("created_at",{ascending:!0});if(n)throw console.error("[ReadStatusRepository] Failed to get thread replies:",n),n;if(!s||0===s.length)return 0;let r=[...new Set(s.map(e=>e.parent_message_id))],d=new Map;for(let s of r)if(s)try{let n=await this.getReadPosition(e,t,s);d.set(s,(null==n?void 0:n.lastReadAt)||a)}catch(e){console.warn("[ReadStatusRepository] Failed to get thread read position for thread ".concat(s,", using channel default:"),e),d.set(s,a)}let i=0;for(let e of s){if(!e.parent_message_id||!e.created_at)continue;let t=d.get(e.parent_message_id)||a;e.created_at>t&&i++}return i}async getUnreadMessageIds(e,t,a){let s="1970-01-01T00:00:00Z";try{let n=await this.getReadPosition(e,t,a);(null==n?void 0:n.lastReadAt)&&(s=n.lastReadAt)}catch(e){console.warn("[ReadStatusRepository] Failed to get read position for unread IDs, using default:",e)}let n=this.supabase.from("team_chat_messages").select("id").eq("channel_id",t).gt("created_at",s).is("deleted_at",null).order("created_at",{ascending:!0});a&&(n=n.eq("parent_message_id",a));let{data:r,error:d}=await n;if(d)throw console.error("[ReadStatusRepository] Failed to get unread message IDs:",d),d;return(null==r?void 0:r.map(e=>e.id))||[]}async getAllReadPositions(e){let{data:t,error:a}=await this.supabase.from("team_chat_read_status").select("\n *,\n channel:team_chat_channels!inner(id, workspace_id)\n ").eq("member_id",e);if(a)throw console.error("[ReadStatusRepository] Failed to get all read positions:",a),a;return(null==t?void 0:t.map(e=>({id:e.id,memberId:e.member_id,channelId:e.channel_id,parentMessageId:null,lastReadMessageId:e.last_read_message_id||"",lastReadAt:e.updated_at||"1970-01-01T00:00:00Z",contextType:"channel"})))||[]}async getUnreadCountsBatch(e,t){let a=new Map,{data:s}=await this.supabase.from("team_chat_read_status").select("channel_id, updated_at").eq("member_id",e).in("channel_id",t),n=new Map;
1null==s||s.forEach(e=>{n.set(e.channel_id,e.updated_at||"1970-01-01T00:00:00Z")});let r=t.map(async t=>{let s=n.get(t)||"1970-01-01T00:00:00Z",{count:r}=await this.supabase.from("team_chat_messages").select("*",{count:"exact",head:!0}).eq("channel_id",t).gt("created_at",s).neq("sender_member_id",e).is("deleted_at",null);a.set(t,r||0)});return await Promise.all(r),a}async deleteReadPosition(e,t){let{error:a}=await this.supabase.from("team_chat_read_status").delete().eq("channel_id",t).eq("member_id",e);if(a)throw console.error("[ReadStatusRepository] Failed to delete read position:",a),a}async deleteReadPositionsByChannel(e){let{error:t}=await this.supabase.from("team_chat_read_status").delete().eq("channel_id",e);if(t)throw console.error("[ReadStatusRepository] Failed to delete read positions by channel:",t),t}constructor(e){this.supabase=e}}class r{async getRepository(){if(!this.repository){let e=await (0,s.db)();this.repository=new n(e)}return this.repository}async markChannelRead(e,t,a){let n=await (0,s.db)(),{data:r,error:d}=await n.from("team_chat_messages").select("id, created_at").eq("id",a).single();if(d||!r)throw Error("Message not found: ".concat(a));let i={memberId:e,channelId:t,parentMessageId:null,lastReadMessageId:a,lastReadAt:r.created_at||new Date().toISOString(),contextType:"channel"},o=await this.getRepository();await o.upsertReadPosition(i)}async markThreadRead(e,t,a,n){let r=await (0,s.db)(),{data:d,error:i}=await r.from("team_chat_messages").select("id, created_at, parent_message_id").eq("id",n).single();if(i||!d)throw Error("Message not found: ".concat(n));if(d.parent_message_id&&d.parent_message_id!==a)throw Error("Message ".concat(n," does not belong to thread ").concat(a));let o={memberId:e,channelId:t,parentMessageId:a,lastReadMessageId:n,lastReadAt:d.created_at||new Date().toISOString(),contextType:"thread"},l=await this.getRepository();await l.upsertReadPosition(o),await this.updateChannelReadIfNecessary(e,t,d.created_at||new Date().toISOString())}async getUnreadCounts(e,t){let a=await this.getRepository(),[s,n,r,d]=await Promise.all([a.getUnreadMessageCount(e,t),a.getUnreadMessageCount(e,t,"threads"),this.checkHasMention(e,t),this.checkHasImportantThreads(e,t)]);return{channelUnreadCount:s,threadUnreadCount:n,hasMention:r,hasImportantThread:d}}async checkHasImportantThreads(e,t){let a=await (0,s.db)(),n=await this.getRepository(),r=await n.getReadPosition(e,t),d=(null==r?void 0:r.lastReadAt)||"1970-01-01T00:00:00Z",{data:i,error:o}=await a.from("team_chat_messages").select("id, parent_message_id").eq("channel_id",t).gt("created_at",d).neq("sender_member_id",e).is("deleted_at",null).not("parent_message_id","is",null);if(o||!i||0===i.length)return!1;let l=[...new Set(i.map(e=>e.parent_message_id).filter(Boolean))],{data:c,error:_}=await a.from("team_chat_messages").select("id, sender_member_id").in("id",l).is("deleted_at",null);return!_&&!!c&&c.some(t=>t.sender_member_id===e)}async checkHasMention(e,t){let a=await (0,s.db)(),n=await this.getRepository(),r=await n.getReadPosition(e,t),d=(null==r?void 0:r.lastReadAt)||"1970-01-01T00:00:00Z",{data:i,error:o}=await a.from("team_chat_messages").select("\n id,\n mentions:team_chat_mentions!inner(\n mention_type,\n mentioned_member_id\n )\n ").eq("channel_id",t).gt("created_at",d).neq("sender_member_id",e).is("deleted_at",null);return!o&&!!i&&i.some(t=>{var a;return null==(a=t.mentions)?void 0:a.some(t=>"user"===t.mention_type&&t.mentioned_member_id===e||"channel"===t.mention_type||"everyone"===t.mention_type||"here"===t.mention_type)})}async updateChannelReadIfNecessary(e,t,a){let n=await (0,s.db)(),r=await this.getRepository(),d=await r.getReadPosition(e,t);if(!d||a>d.lastReadAt){let{data:s}=await n.from("team_chat_messages").select("id").eq("channel_id",t).lte("created_at",a).is("deleted_at",null).order("created_at",{ascending:!1}).limit(1).single();s&&await this.markChannelRead(e,t,s.id)}}async markMessagesAsReadUpTo(e,t,a){let n=await (0,s.db)(),{data:r}=await n.from("team_chat_messages").select("parent_message_id").eq("id",t).single();(null==r?void 0:r.parent_message_id)?await this.markThreadRead(a,e,r.parent_message_id,t):await this.markChannelRead(a,e,t)}async getWorkspaceUnreadSummary(e,t){let a=await (0,s.db)(),{data:n}=await a.from("team_chat_channel_members").select("\n channel_id,\n channel:team_chat_channels!inner(\n id,\n name,\n type,\n deleted_at,\n workspace_id\n )\n ").eq("member_id",t).eq("channel.workspace_id",e).is("channel.deleted_at",null);if(!n)return{totalUnread:0,totalMentions:0,channels:[]};let r=0,d=0,i=[],o=n.map(async e=>{let s=e.channel_id,{data:n}=await a.from("team_chat_messages").select("created_at").eq("channel_id",s).is("deleted_at",null).order("created_at",{ascending:!1}).limit(1),i=null==n?void 0:n[0];if(!i)return null;let o=await this.getUnreadCounts(t,s),l=await this.getRepository(),c=await l.getReadPosition(t,s),_=(null==c?void 0:c.lastReadAt)||null;return r+=o.channelUnreadCount,o.hasMention&&d++,{channelId:s,unreadCount:o.channelUnreadCount,lastReadAt:_,lastReadMessageId:null==c?void 0:c.lastReadMessageId,lastMessageAt:i.created_at||"",hasMention:o.hasMention,hasImportantThread:o.hasImportantThread}});return i.push(...(await Promise.all(o)).filter(e=>null!==e)),{totalUnread:r,totalMentions:d,channels:i}}constructor(){this.repository=null}}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.