smodusermc commited on
Commit
6bc3c34
·
verified ·
1 Parent(s): 83f4dc7

Update static/script.js

Browse files
Files changed (1) hide show
  1. static/script.js +63 -11
static/script.js CHANGED
@@ -124,7 +124,8 @@
124
  convOptionsBtn: $('conv-options-btn'), convOptionsModal: $('conv-options-modal'),
125
  convOptionsTitle: $('conv-options-title'),
126
  renameConvBtn: $('rename-conv-btn'), addGroupMembersBtn: $('add-group-members-btn'),
127
- blockConvUserBtn: $('block-conv-user-btn'), leaveConvBtn: $('leave-conv-btn'),
 
128
  refreshBlocksBtn: $('refresh-blocks-btn'), blockedUsersList: $('blocked-users-list'),
129
 
130
  settingsDisplayName: $('settings-display-name'), settingsUsername: $('settings-username'),
@@ -758,10 +759,14 @@
758
  State.isAtBottom = true;
759
 
760
  const cache = getConv(convId);
 
761
  renderConversationHeader(convId);
762
  renderSidebar();
763
 
764
- if (cache.ids.length === 0) {
 
 
 
765
  cache.loading = true;
766
  loadMessages(convId);
767
  renderEmptyLoading(convId);
@@ -791,6 +796,18 @@
791
  DOM.loadOlderBtn.classList.add('hidden');
792
  }
793
 
 
 
 
 
 
 
 
 
 
 
 
 
794
  function renderConversationHeader(convId) {
795
  const conv = convById(convId);
796
  if (!conv) return;
@@ -813,9 +830,15 @@
813
  const online = peer.online || State.onlineUsers.has(peer.id);
814
  DOM.convPresenceDot.classList.remove('hidden');
815
  DOM.convPresenceDot.classList.toggle('offline', !online);
816
- DOM.convSubtitle.innerHTML = online
817
- ? '<span class="status-dot online"></span> Online'
818
- : escapeHtml(formatLastSeen(peer.last_seen));
 
 
 
 
 
 
819
  DOM.onlineBtn.style.display = '';
820
  DOM.convAvatarPh.style.display = '';
821
  DOM.convAvatar.style.display = '';
@@ -1018,6 +1041,9 @@
1018
  if (msg.conversation.id === State.activeConvId) {
1019
  renderConversationHeader(State.activeConvId);
1020
  }
 
 
 
1021
  break;
1022
 
1023
  case 'conversation_deleted': {
@@ -1027,7 +1053,7 @@
1027
  State.messages.forEach(m => { if (m.conversation_id === cid) State.messages.delete(m.id); });
1028
  if (State.activeConvId === cid) switchConversation(GLOBAL_CONV);
1029
  renderSidebar();
1030
- showToast('A group chat was deleted', 'info');
1031
  break;
1032
  }
1033
 
@@ -1039,6 +1065,10 @@
1039
  if (State.activeConvId === cid) switchConversation(GLOBAL_CONV);
1040
  } else if (msg.conversation) {
1041
  upsertConversation(msg.conversation);
 
 
 
 
1042
  }
1043
  renderSidebar();
1044
  break;
@@ -1066,7 +1096,7 @@
1066
  upsertConversation(msg.conversation);
1067
  const peer = msg.conversation.peer;
1068
  if (peer && peer.id !== State.user?.id) {
1069
- showToast(`Private chat with ${displayNameOf(peer)} created`, 'success');
1070
  switchConversation(msg.conversation.id);
1071
  }
1072
  break;
@@ -2068,7 +2098,7 @@
2068
  if (!content && !State.pendingFile) return;
2069
  if (!State.activeConvId) { showToast('No conversation selected', 'warning'); return; }
2070
  const active = convById(State.activeConvId);
2071
- if (active && active.is_pending) { showToast('Accept the group invite first', 'warning'); return; }
2072
  if (!wsOpen()) {
2073
  showToast('Not connected - message queued, sending when reconnected', 'warning');
2074
  }
@@ -2224,7 +2254,7 @@
2224
  upsertConversation(data.conversation);
2225
  closeModal(DOM.convModal);
2226
  switchConversation(data.conversation.id);
2227
- showToast(`Private chat with ${peerName} started`, 'success');
2228
  } catch (err) {
2229
  showToast(err.message, 'error');
2230
  finish();
@@ -2516,12 +2546,12 @@
2516
  if (action === 'accept') {
2517
  upsertConversation(data.conversation);
2518
  switchConversation(cid);
2519
- showToast('Group invite accepted', 'success');
2520
  } else {
2521
  State.conversations.delete(cid);
2522
  State.convCache.delete(cid);
2523
  renderSidebar();
2524
- showToast('Group invite rejected', 'info');
2525
  }
2526
  } catch (err) {
2527
  showToast(err.message, 'error');
@@ -2656,6 +2686,7 @@
2656
  const pending = !!conv.is_pending;
2657
  DOM.renameConvBtn.style.display = pending ? 'none' : '';
2658
  DOM.addGroupMembersBtn.style.display = conv.is_group && !pending ? '' : 'none';
 
2659
  DOM.blockConvUserBtn.style.display = (!conv.is_group && conv.peer) ? '' : 'none';
2660
  DOM.leaveConvBtn.style.display = (conv.is_group && !pending) ? '' : 'none';
2661
  DOM.convOptionsTitle.innerHTML = `<i class="fas fa-ellipsis-h"></i> ${escapeHtml(conv.custom_name || conv.title || 'Chat Options')}`;
@@ -2695,6 +2726,27 @@
2695
  openModal(DOM.groupModal);
2696
  });
2697
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2698
  DOM.blockConvUserBtn.addEventListener('click', async () => {
2699
  const conv = convById(State.activeConvId);
2700
  closeModal(DOM.convOptionsModal);
 
124
  convOptionsBtn: $('conv-options-btn'), convOptionsModal: $('conv-options-modal'),
125
  convOptionsTitle: $('conv-options-title'),
126
  renameConvBtn: $('rename-conv-btn'), addGroupMembersBtn: $('add-group-members-btn'),
127
+ deleteConvBtn: $('delete-conv-btn'), blockConvUserBtn: $('block-conv-user-btn'),
128
+ leaveConvBtn: $('leave-conv-btn'),
129
  refreshBlocksBtn: $('refresh-blocks-btn'), blockedUsersList: $('blocked-users-list'),
130
 
131
  settingsDisplayName: $('settings-display-name'), settingsUsername: $('settings-username'),
 
759
  State.isAtBottom = true;
760
 
761
  const cache = getConv(convId);
762
+ const conv = convById(convId);
763
  renderConversationHeader(convId);
764
  renderSidebar();
765
 
766
+ if (conv && conv.is_pending) {
767
+ cache.loading = false;
768
+ renderPendingInvite(convId);
769
+ } else if (cache.ids.length === 0) {
770
  cache.loading = true;
771
  loadMessages(convId);
772
  renderEmptyLoading(convId);
 
796
  DOM.loadOlderBtn.classList.add('hidden');
797
  }
798
 
799
+ function renderPendingInvite(convId) {
800
+ DOM.messagesList.innerHTML = '';
801
+ if (DOM.emptyState.parentNode !== DOM.messagesList) DOM.messagesList.appendChild(DOM.emptyState);
802
+ const conv = convById(convId);
803
+ const name = conv ? (conv.custom_name || conv.title || (conv.peer ? displayNameOf(conv.peer) : 'this chat')) : 'this chat';
804
+ DOM.emptyIcon.innerHTML = '<i class="fas fa-envelope-open-text"></i>';
805
+ DOM.emptyTitle.textContent = 'Invite pending';
806
+ DOM.emptySub.textContent = `Accept the invite for ${name} from the sidebar to start chatting.`;
807
+ DOM.emptyState.style.display = 'flex';
808
+ DOM.loadOlderBtn.classList.add('hidden');
809
+ }
810
+
811
  function renderConversationHeader(convId) {
812
  const conv = convById(convId);
813
  if (!conv) return;
 
830
  const online = peer.online || State.onlineUsers.has(peer.id);
831
  DOM.convPresenceDot.classList.remove('hidden');
832
  DOM.convPresenceDot.classList.toggle('offline', !online);
833
+ if (conv.peer_removed) {
834
+ DOM.convSubtitle.innerHTML = '<span class="status-dot warn"></span> They no longer want to chat';
835
+ } else if (conv.is_pending) {
836
+ DOM.convSubtitle.innerHTML = '<span class="status-dot warn"></span> Invite pending — accept to start chatting';
837
+ } else {
838
+ DOM.convSubtitle.innerHTML = online
839
+ ? '<span class="status-dot online"></span> Online'
840
+ : escapeHtml(formatLastSeen(peer.last_seen));
841
+ }
842
  DOM.onlineBtn.style.display = '';
843
  DOM.convAvatarPh.style.display = '';
844
  DOM.convAvatar.style.display = '';
 
1041
  if (msg.conversation.id === State.activeConvId) {
1042
  renderConversationHeader(State.activeConvId);
1043
  }
1044
+ if (msg.invite_rejected && msg.rejected_user_id && msg.rejected_user_id !== State.user?.id) {
1045
+ showToast('The invite was declined', 'info');
1046
+ }
1047
  break;
1048
 
1049
  case 'conversation_deleted': {
 
1053
  State.messages.forEach(m => { if (m.conversation_id === cid) State.messages.delete(m.id); });
1054
  if (State.activeConvId === cid) switchConversation(GLOBAL_CONV);
1055
  renderSidebar();
1056
+ showToast('The chat was deleted', 'info');
1057
  break;
1058
  }
1059
 
 
1065
  if (State.activeConvId === cid) switchConversation(GLOBAL_CONV);
1066
  } else if (msg.conversation) {
1067
  upsertConversation(msg.conversation);
1068
+ if (msg.reason === 'deleted') {
1069
+ const peer = msg.conversation.peer;
1070
+ showToast(`${peer ? displayNameOf(peer) : 'The other person'} no longer wants to chat`, 'info');
1071
+ }
1072
  }
1073
  renderSidebar();
1074
  break;
 
1096
  upsertConversation(msg.conversation);
1097
  const peer = msg.conversation.peer;
1098
  if (peer && peer.id !== State.user?.id) {
1099
+ showToast(`Private chat with ${displayNameOf(peer)} started — waiting for them to accept`, 'success');
1100
  switchConversation(msg.conversation.id);
1101
  }
1102
  break;
 
2098
  if (!content && !State.pendingFile) return;
2099
  if (!State.activeConvId) { showToast('No conversation selected', 'warning'); return; }
2100
  const active = convById(State.activeConvId);
2101
+ if (active && active.is_pending) { showToast('Accept the invite first', 'warning'); return; }
2102
  if (!wsOpen()) {
2103
  showToast('Not connected - message queued, sending when reconnected', 'warning');
2104
  }
 
2254
  upsertConversation(data.conversation);
2255
  closeModal(DOM.convModal);
2256
  switchConversation(data.conversation.id);
2257
+ showToast(`Private chat with ${peerName} started — waiting for them to accept`, 'success');
2258
  } catch (err) {
2259
  showToast(err.message, 'error');
2260
  finish();
 
2546
  if (action === 'accept') {
2547
  upsertConversation(data.conversation);
2548
  switchConversation(cid);
2549
+ showToast('Invite accepted', 'success');
2550
  } else {
2551
  State.conversations.delete(cid);
2552
  State.convCache.delete(cid);
2553
  renderSidebar();
2554
+ showToast('Invite declined', 'info');
2555
  }
2556
  } catch (err) {
2557
  showToast(err.message, 'error');
 
2686
  const pending = !!conv.is_pending;
2687
  DOM.renameConvBtn.style.display = pending ? 'none' : '';
2688
  DOM.addGroupMembersBtn.style.display = conv.is_group && !pending ? '' : 'none';
2689
+ DOM.deleteConvBtn.style.display = (!conv.is_group && conv.peer && !pending) ? '' : 'none';
2690
  DOM.blockConvUserBtn.style.display = (!conv.is_group && conv.peer) ? '' : 'none';
2691
  DOM.leaveConvBtn.style.display = (conv.is_group && !pending) ? '' : 'none';
2692
  DOM.convOptionsTitle.innerHTML = `<i class="fas fa-ellipsis-h"></i> ${escapeHtml(conv.custom_name || conv.title || 'Chat Options')}`;
 
2726
  openModal(DOM.groupModal);
2727
  });
2728
 
2729
+ DOM.deleteConvBtn.addEventListener('click', async () => {
2730
+ const conv = convById(State.activeConvId);
2731
+ closeModal(DOM.convOptionsModal);
2732
+ if (!conv || conv.is_group || !conv.peer) return;
2733
+ const ok = await showConfirm({
2734
+ title: 'Delete private chat',
2735
+ message: `Delete this chat with ${displayNameOf(conv.peer)}? It will be hidden for you. If they also delete it, it is removed for everyone. They will be told that you no longer want to chat.`,
2736
+ okText: 'Delete Chat'
2737
+ });
2738
+ if (!ok) return;
2739
+ try {
2740
+ const data = await apiDelete(`/api/conversations/${conv.id}`);
2741
+ State.conversations.delete(conv.id);
2742
+ State.convCache.delete(conv.id);
2743
+ if (State.activeConvId === conv.id) switchConversation(GLOBAL_CONV);
2744
+ renderSidebar();
2745
+ showToast(data.status === 'deleted' ? 'Chat deleted' : 'Chat hidden for you', 'success');
2746
+ requestConversations();
2747
+ } catch (err) { showToast(err.message, 'error'); }
2748
+ });
2749
+
2750
  DOM.blockConvUserBtn.addEventListener('click', async () => {
2751
  const conv = convById(State.activeConvId);
2752
  closeModal(DOM.convOptionsModal);