-
Notifications
You must be signed in to change notification settings - Fork 4
Support inbox messages #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
clabland
wants to merge
8
commits into
develop
Choose a base branch
from
INAPP-13667
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+809
−7
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
e4098ec
Support inbox messages
clabland 96df16c
Merge branch 'develop' into INAPP-13667
clabland c79aa02
Review feedback
clabland d24529f
lint
clabland 27c222d
Send updated message list when marking opened or deleted
clabland b41616d
Support marking unopened and unsubscribing from event emitter
clabland 860f642
Send opened inboxMessageAction events; add test harness config section
clabland 9988768
Review feedback
clabland File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| async function refreshInboxMessages(messages) { | ||
| const unopenedCount = await window.Gist.getInboxUnopenedCount(); | ||
| const badge = document.getElementById('inboxBadge'); | ||
| if (unopenedCount > 0) { | ||
| badge.textContent = unopenedCount; | ||
| badge.style.display = 'inline-block'; | ||
| } else { | ||
| badge.style.display = 'none'; | ||
| } | ||
|
|
||
| if (!messages) { | ||
| messages = await window.Gist.getInboxMessages(); | ||
| } | ||
|
|
||
| const content = document.getElementById('inboxPanelContent'); | ||
|
|
||
| if (messages.length === 0) { | ||
| content.innerHTML = '<p class="no-messages">No messages</p>'; | ||
| return; | ||
| } | ||
|
|
||
| let html = ''; | ||
| for (const message of messages) { | ||
| const props = message.properties || {}; | ||
| const queueId = message.queueId; | ||
| const propertiesJson = JSON.stringify(props, null, 2); | ||
|
|
||
| html += ` | ||
| <div class="inbox-message ${!message.opened ? 'unopened' : ''}" data-queue-id="${queueId}"> | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <div class="inbox-message-header"> | ||
| <strong>Properties</strong> | ||
| <p>Sent at ${new Date(message.sentAt).toLocaleString()}</p> | ||
| ${!message.opened ? '<span class="unopened-dot"></span>' : ''} | ||
| </div> | ||
| <div class="inbox-message-body"> | ||
| <pre>${propertiesJson}</pre> | ||
| </div> | ||
| <div class="inbox-message-actions"> | ||
| ${!message.opened ? `<button onclick="updateInboxMessageOpenState('${queueId}',true)">Mark as opened</button>` : `<button onclick="updateInboxMessageOpenState('${queueId}',false)">Mark as unopened</button>`} | ||
| <button onclick="deleteMessage('${queueId}')">Delete</button> | ||
| </div> | ||
| </div> | ||
| `; | ||
| } | ||
|
|
||
| content.innerHTML = html; | ||
| } | ||
|
|
||
| // eslint-disable-next-line no-unused-vars | ||
| async function updateInboxMessageOpenState(queueId, opened) { | ||
| try { | ||
| await window.Gist.updateInboxMessageOpenState(queueId, opened); | ||
| } catch (error) { | ||
| console.error('Failed to mark message as opened:', error); | ||
| alert('Failed to mark message as read. Please try again.'); | ||
| } | ||
| } | ||
|
|
||
| // eslint-disable-next-line no-unused-vars | ||
| async function deleteMessage(queueId) { | ||
| try { | ||
| await window.Gist.removeInboxMessage(queueId); | ||
| } catch (error) { | ||
| console.error('Failed to delete message:', error); | ||
| alert('Failed to delete message. Please try again.'); | ||
| } | ||
| } | ||
|
|
||
| document.querySelectorAll(".toggle-inbox").forEach(element => { | ||
| element.addEventListener("click", () => { | ||
| const panel = document.getElementById('inboxPanel'); | ||
| if (panel.style.display === 'none') { | ||
| panel.style.display = 'block'; | ||
| } else { | ||
| panel.style.display = 'none'; | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| refreshInboxMessages(); | ||
|
|
||
| window.Gist.events.on('messageInboxUpdated', async function(messages) { | ||
| await refreshInboxMessages(messages); | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| // Default configuration | ||
| const defaultConfig = { | ||
| siteId: "a5ec106751ef4b34a0b9", | ||
| dataCenter: "eu", | ||
| env: "prod", | ||
| logging: true, | ||
| useAnonymousSession: true, | ||
| userToken: "ABC123" | ||
| }; | ||
|
|
||
| // Load configuration from localStorage or use defaults | ||
| function loadConfig() { | ||
| const savedConfig = localStorage.getItem('gistConfig'); | ||
| return savedConfig ? JSON.parse(savedConfig) : defaultConfig; | ||
| } | ||
|
|
||
| // Get current configuration | ||
| // eslint-disable-next-line no-unused-vars | ||
| function getConfig() { | ||
| return loadConfig(); | ||
| } | ||
|
|
||
| // Populate form with current config | ||
| function populateConfigForm() { | ||
| const config = loadConfig(); | ||
| document.getElementById('siteId').value = config.siteId; | ||
| document.getElementById('dataCenter').value = config.dataCenter; | ||
| document.getElementById('env').value = config.env; | ||
| document.getElementById('logging').checked = config.logging; | ||
| document.getElementById('useAnonymousSession').checked = config.useAnonymousSession; | ||
| document.getElementById('userToken').value = config.userToken; | ||
| } | ||
|
|
||
| // Toggle config form visibility | ||
| // eslint-disable-next-line no-unused-vars | ||
| function toggleConfigForm() { | ||
| const content = document.getElementById('configFormContent'); | ||
| const icon = document.getElementById('configToggleIcon'); | ||
| if (content.style.display === 'none' || !content.style.display) { | ||
| content.style.display = 'block'; | ||
| icon.textContent = '▲'; | ||
| } else { | ||
| content.style.display = 'none'; | ||
| icon.textContent = '▼'; | ||
| } | ||
| } | ||
|
|
||
| // Save config and reload page | ||
| // eslint-disable-next-line no-unused-vars | ||
| function saveConfig(event) { | ||
| event.preventDefault(); | ||
| const newConfig = { | ||
| siteId: document.getElementById('siteId').value, | ||
| dataCenter: document.getElementById('dataCenter').value, | ||
| env: document.getElementById('env').value, | ||
| logging: document.getElementById('logging').checked, | ||
| useAnonymousSession: document.getElementById('useAnonymousSession').checked, | ||
| userToken: document.getElementById('userToken').value | ||
| }; | ||
| localStorage.setItem('gistConfig', JSON.stringify(newConfig)); | ||
| window.location.reload(); | ||
| } | ||
|
|
||
| // Reset to default config | ||
| // eslint-disable-next-line no-unused-vars | ||
| function resetConfig() { | ||
| if (confirm('Are you sure you want to reset to default configuration?')) { | ||
| localStorage.removeItem('gistConfig'); | ||
| window.location.reload(); | ||
| } | ||
| } | ||
|
|
||
| // Initialize form on page load | ||
| window.addEventListener('DOMContentLoaded', function() { | ||
| populateConfigForm(); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Badge count and message list use different data sources
When
refreshInboxMessagesis called with amessagesparameter (from themessageInboxUpdatedevent), the badge count is still fetched separately viagetInboxUnopenedCount()which reads from localStorage. This causes the badge count and the rendered message list to potentially show inconsistent data - the badge reflects filtered/stored messages while the list renders the event's messages. The unopened count calculation needs to use the samemessagesarray when it's provided.