|
829 | 829 | this.nicknameColors = new Map(); // Map nickname to color |
830 | 830 | this.messagesByMessageId = new Map(); // Store messages by their ID for replies |
831 | 831 | this.replyingTo = null; // Current reply context |
| 832 | + this.notificationsEnabled = false; // Track if notifications are enabled |
832 | 833 |
|
833 | 834 | this.initProtobuf(); |
834 | 835 | this.initElements(); |
835 | 836 | this.initEventListeners(); |
| 837 | + this.requestNotificationPermission(); |
836 | 838 | this.initWaku(); |
837 | 839 | } |
838 | 840 |
|
|
874 | 876 | return nickname; |
875 | 877 | } |
876 | 878 |
|
| 879 | + async requestNotificationPermission() { |
| 880 | + if (!('Notification' in window)) { |
| 881 | + console.log('This browser does not support notifications'); |
| 882 | + this.addSystemMessage('Browser notifications not supported'); |
| 883 | + return; |
| 884 | + } |
| 885 | + |
| 886 | + if (Notification.permission === 'granted') { |
| 887 | + this.notificationsEnabled = true; |
| 888 | + this.addSystemMessage('Browser notifications enabled'); |
| 889 | + return; |
| 890 | + } |
| 891 | + |
| 892 | + if (Notification.permission !== 'denied') { |
| 893 | + try { |
| 894 | + const permission = await Notification.requestPermission(); |
| 895 | + if (permission === 'granted') { |
| 896 | + this.notificationsEnabled = true; |
| 897 | + this.addSystemMessage('Browser notifications enabled'); |
| 898 | + } else { |
| 899 | + this.addSystemMessage('Browser notifications disabled'); |
| 900 | + } |
| 901 | + } catch (error) { |
| 902 | + console.error('Error requesting notification permission:', error); |
| 903 | + this.addSystemMessage('Failed to request notification permission'); |
| 904 | + } |
| 905 | + } else { |
| 906 | + this.addSystemMessage('Browser notifications blocked'); |
| 907 | + } |
| 908 | + } |
| 909 | + |
| 910 | + createNotification(sender, text, isReply = false) { |
| 911 | + if (!this.notificationsEnabled || sender === this.nickname) { |
| 912 | + return; // Don't show notifications for our own messages |
| 913 | + } |
| 914 | + |
| 915 | + try { |
| 916 | + const title = isReply ? `${sender} replied in RetroChat` : `${sender} in RetroChat`; |
| 917 | + const body = text.length > 100 ? text.substring(0, 100) + '...' : text; |
| 918 | + |
| 919 | + const notification = new Notification(title, { |
| 920 | + body: body, |
| 921 | + tag: 'retro-chat-message', |
| 922 | + requireInteraction: false, |
| 923 | + silent: false |
| 924 | + }); |
| 925 | + |
| 926 | + // Auto-close notification after 5 seconds |
| 927 | + setTimeout(() => { |
| 928 | + notification.close(); |
| 929 | + }, 5000); |
| 930 | + |
| 931 | + // Focus window when notification is clicked |
| 932 | + notification.onclick = () => { |
| 933 | + window.focus(); |
| 934 | + notification.close(); |
| 935 | + }; |
| 936 | + |
| 937 | + } catch (error) { |
| 938 | + console.error('Error creating notification:', error); |
| 939 | + console.error('Error details:', error.message); |
| 940 | + } |
| 941 | + } |
| 942 | + |
877 | 943 | initProtobuf() { |
878 | 944 | const root = window.protobuf.parse(protoSchema).root; |
879 | 945 | this.Chat2Message = root.lookupType('Chat2Message'); |
|
1585 | 1651 | // Add the message to chat |
1586 | 1652 | this.addChatMessage(message); |
1587 | 1653 |
|
| 1654 | + // Create notification for the new message |
| 1655 | + const isReply = !!message.replyToMessageId; |
| 1656 | + this.createNotification(message.sender, message.text, isReply); |
| 1657 | + |
1588 | 1658 | } catch (error) { |
1589 | 1659 | console.error('Failed to process incoming message:', error); |
1590 | 1660 | } |
|
0 commit comments