diff --git a/app/SysTray-X/preferences.cpp b/app/SysTray-X/preferences.cpp index b9cfb06..5794c61 100644 --- a/app/SysTray-X/preferences.cpp +++ b/app/SysTray-X/preferences.cpp @@ -40,13 +40,11 @@ Preferences::Preferences( QObject *parent ) : QObject( parent ) m_show_number = true; m_number_color = "#000000"; + m_count_type = PREF_COUNT_UNREAD; m_minimize_type = PREF_DEFAULT_MINIMIZE; m_start_minimized = false; - m_poll_startup_delay = 60; - m_poll_interval = 60; - m_debug = false; m_version_major = QLatin1String( APP_VERSION_MAJOR ); @@ -266,6 +264,31 @@ void Preferences::setNumberColor( QString color ) } +/* + * Get the count type. + */ +Preferences::CountType Preferences::getCountType() const +{ + return m_count_type; +} + + +/* + * Set the count type. + */ +void Preferences::setCountType( CountType count_type ) +{ + if( m_count_type != count_type) + { + m_count_type = count_type; + + /* + * Tell the world the new preference + */ + emit signalCountTypeChange(); + } +} + /* * Get the icon type. */ @@ -318,58 +341,6 @@ void Preferences::setStartMinimized( bool state ) } -/* - * Get the poll startup delay. - */ -int Preferences::getPollStartupDelay() const -{ - return m_poll_startup_delay; -} - - -/* - * Set the startup poll delay. - */ -void Preferences::setPollStartupDelay( int val ) -{ - if( m_poll_startup_delay != val ) - { - m_poll_startup_delay = val; - - /* - * Tell the world the new preference - */ - emit signalPollStartupDelayChange(); - } -} - - -/* - * Get the poll interval. - */ -int Preferences::getPollInterval() const -{ - return m_poll_interval; -} - - -/* - * Set the startup poll delay. - */ -void Preferences::setPollInterval( int val ) -{ - if( m_poll_interval != val ) - { - m_poll_interval = val; - - /* - * Tell the world the new preference - */ - emit signalPollIntervalChange(); - } -} - - /* * Get the debug state. */ diff --git a/app/SysTray-X/preferences.h b/app/SysTray-X/preferences.h index 9c8cd35..4ad304b 100644 --- a/app/SysTray-X/preferences.h +++ b/app/SysTray-X/preferences.h @@ -39,6 +39,14 @@ class Preferences : public QObject PREF_CUSTOM_ICON }; + /* + * Count types + */ + enum CountType { + PREF_COUNT_UNREAD = 0, + PREF_COUNT_NEW + }; + /* * Window states */ @@ -197,6 +205,20 @@ class Preferences : public QObject */ void setNumberColor( QString color ); + /** + * @brief getCountType. Get the count type. + * + * @return The count type. + */ + CountType getCountType() const; + + /** + * @brief setCountType. Set the count type. + * + * @param The count type. + */ + void setCountType( CountType count_type ); + /** * @brief getMinimizeType. Get the minimize type. * @@ -225,34 +247,6 @@ class Preferences : public QObject */ void setStartMinimized( bool state ); - /** - * @brief getPollStartupDelay. Get the poll startup delay. - * - * @return The poll startup delay. - */ - int getPollStartupDelay() const; - - /** - * @brief setPollStartupDelay. Set the poll startup delay. - * - * @param The poll startup delay. - */ - void setPollStartupDelay( int val ); - - /** - * @brief getPollInterval. Get the poll interval. - * - * @return The poll interval. - */ - int getPollInterval() const; - - /** - * @brief setPollInterval. Set the poll interval. - * - * @param The poll interval. - */ - void setPollInterval( int val ); - /** * @brief getDebug. Get the debug windows state. * @@ -324,6 +318,11 @@ class Preferences : public QObject */ void signalNumberColorChange(); + /** + * @brief signalCountTypeChange. Signal a count type change. + */ + void signalCountTypeChange(); + /** * @brief signalMinimizeTypeChange. Signal a minimize type change. */ @@ -334,16 +333,6 @@ class Preferences : public QObject */ void signalStartMinimizedChange(); - /** - * @brief signalPollStartupDelayChange. Signal a poll startup delay change. - */ - void signalPollStartupDelayChange(); - - /** - * @brief signalPollIntervalChange. Signal a poll interval change. - */ - void signalPollIntervalChange(); - /** * @brief signalDebugChange. Signal a debug state change. */ @@ -396,6 +385,11 @@ class Preferences : public QObject */ QString m_number_color; + /** + * @brief m_count_type. Selected count type. + */ + CountType m_count_type; + /** * @brief m_minimize_type. Selected minimize type. */ @@ -406,16 +400,6 @@ class Preferences : public QObject */ bool m_start_minimized; - /** - * @brief m_poll_startup_delay. The startup poll delay. - */ - int m_poll_startup_delay; - - /** - * @brief m_poll_interval. The poll interval. - */ - int m_poll_interval; - /** * @brief m_debug. Display debug window. */ diff --git a/app/SysTray-X/preferences.ui b/app/SysTray-X/preferences.ui index 7746ce8..0b9196b 100644 --- a/app/SysTray-X/preferences.ui +++ b/app/SysTray-X/preferences.ui @@ -6,8 +6,8 @@ 0 0 - 583 - 261 + 482 + 442 @@ -17,207 +17,10 @@ :/files/icons/SysTray-X.png:/files/icons/SysTray-X.png - - - - - - - Number properties - - - - - - - - Display unread message count - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Text color - - - - - - - Qt::NoFocus - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - Mail actions - - - - - - - - Poll startup delay - - - - - - - 1 - - - 999 - - - 60 - - - - - - - Poll interval - - - - - - - 1 - - - 999 - - - 60 - - - - - - - - - - - - Windows - - - - - - - - Minimize - - - - - - Default minimize - - - false - - - minimizeTypeGroup - - - - - - - Minimize to tray, method 1 - - - true - - - minimizeTypeGroup - - - - - - - Minimize to tray, method 2 - - - minimizeTypeGroup - - - - - - - - - - Start application minimized - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - + + + + Mail notification icon @@ -327,7 +130,100 @@ - + + + + Number properties + + + + + + + + Display unread message count + + + true + + + + + + + + + Text color + + + + + + + Qt::NoFocus + + + + + + + + + + + + Count type + + + + + + + + Unread + + + true + + + countTypeGroup + + + + + + + New + + + countTypeGroup + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 17 + 13 + + + + + Display debug window @@ -336,7 +232,89 @@ - + + + + Windows + + + + + + + + Minimize + + + + + + + + Default minimize + + + false + + + minimizeTypeGroup + + + + + + + Minimize to tray, method 1 + + + true + + + minimizeTypeGroup + + + + + + + Minimize to tray, method 2 + + + minimizeTypeGroup + + + + + + + + + + + + Start application minimized + + + + + + + + + + + + Qt::Vertical + + + + 20 + 197 + + + + + Qt::Horizontal @@ -370,7 +348,8 @@ - + + diff --git a/app/SysTray-X/preferencesdialog.cpp b/app/SysTray-X/preferencesdialog.cpp index 9f5fab0..209f4a2 100644 --- a/app/SysTray-X/preferencesdialog.cpp +++ b/app/SysTray-X/preferencesdialog.cpp @@ -51,6 +51,19 @@ PreferencesDialog::PreferencesDialog( SysTrayXLink *link, Preferences *pref, QWi m_ui->iconTypeGroup->setId( m_ui->newMailButton, Preferences::PREF_NEWMAIL_ICON ); m_ui->iconTypeGroup->setId( m_ui->customRadioButton, Preferences::PREF_CUSTOM_ICON ); + /* + * Set count type button Ids + */ + m_ui->countTypeGroup->setId( m_ui->unreadRadioButton, Preferences::PREF_COUNT_UNREAD ); + m_ui->countTypeGroup->setId( m_ui->newRadioButton, Preferences::PREF_COUNT_NEW ); + + /* + * Hide the count type for now + */ + m_ui->countTypeGroupBox->setVisible(false); +// m_ui->unreadRadioButton->setVisible(false); + // m_ui->newRadioButton->setVisible(false); + /* * Set defaults */ @@ -81,24 +94,6 @@ void PreferencesDialog::setDebug( bool state ) } -/* - * Set the poll startup delay - */ -void PreferencesDialog::setPollStartupDelay( int val ) -{ - m_ui->pollStartupDelaySpinBox->setValue( val ); -} - - -/* - * Set the poll interval - */ -void PreferencesDialog::setPollInterval( int val ) -{ - m_ui->pollIntervalSpinBox->setValue( val ); -} - - /* * Set the minimize type */ @@ -184,6 +179,15 @@ void PreferencesDialog::setNumberColor( QString color ) } +/* + * Set the count type + */ +void PreferencesDialog::setCountType( Preferences::CountType count_type ) +{ + ( m_ui->countTypeGroup->button( count_type ) )->setChecked( true ); +} + + /* * Handle the accept signal */ @@ -204,11 +208,9 @@ void PreferencesDialog::slotAccept() m_pref->setMinimizeType( static_cast< Preferences::MinimizeType >( m_ui->minimizeTypeGroup->checkedId() ) ); m_pref->setStartMinimized( m_ui->startMinimizedCheckBox->isChecked() ); - m_pref->setPollStartupDelay(m_ui->pollStartupDelaySpinBox->value()); - m_pref->setPollInterval(m_ui->pollIntervalSpinBox->value()); - m_pref->setShowNumber( m_ui->showNumberCheckBox->isChecked() ); m_pref->setNumberColor( m_number_color ); + m_pref->setCountType( static_cast< Preferences::CountType >( m_ui->countTypeGroup->checkedId() ) ); m_pref->setDebug( m_ui->debugWindowCheckBox->isChecked() ); @@ -287,24 +289,6 @@ void PreferencesDialog::slotDebugChange() } -/* - * Handle the poll startup delay change signal - */ -void PreferencesDialog::slotPollStartupDelayChange() -{ - setPollStartupDelay( m_pref->getPollStartupDelay() ); -} - - -/* - * Handle the poll interval change signal - */ -void PreferencesDialog::slotPollIntervalChange() -{ - setPollInterval( m_pref->getPollInterval() ); -} - - /* * Handle the minimize type change signal */ @@ -363,3 +347,12 @@ void PreferencesDialog::slotNumberColorChange() { setNumberColor( m_pref->getNumberColor() ); } + + +/* + * Handle the count type change signal + */ +void PreferencesDialog::slotCountTypeChange() +{ + setCountType( m_pref->getCountType() ); +} diff --git a/app/SysTray-X/preferencesdialog.h b/app/SysTray-X/preferencesdialog.h index acf6d72..9291f8e 100644 --- a/app/SysTray-X/preferencesdialog.h +++ b/app/SysTray-X/preferencesdialog.h @@ -48,20 +48,6 @@ class PreferencesDialog : public QDialog */ void setDebug( bool state ); - /** - * @brief setPollStartupDelay. Set the poll startup delay. - * - * @param val The new value. - */ - void setPollStartupDelay( int val ); - - /** - * @brief setPollInterval. Set the poll interval. - * - * @param val The new value. - */ - void setPollInterval( int val ); - /** * @brief setMinimizeType. Set the minimize type. * @@ -110,6 +96,13 @@ class PreferencesDialog : public QDialog */ void setNumberColor( QString color ); + /** + * @brief setCountType. Set the count type. + * + * @param count_type The count type. + */ + void setCountType( Preferences::CountType count_type ); + signals: /** @@ -131,16 +124,6 @@ class PreferencesDialog : public QDialog */ void slotDebugChange(); - /** - * @brief slotPollStartupDelayChange. Slot for handling poll startup delay signals. - */ - void slotPollStartupDelayChange(); - - /** - * @brief slotPollIntervalChange. Slot for handling poll interval signals. - */ - void slotPollIntervalChange(); - /** * @brief slotMinimizeTypeChange. Slot for handling minimize type change signals. */ @@ -171,6 +154,11 @@ class PreferencesDialog : public QDialog */ void slotNumberColorChange(); + /** + * @brief slotCountTypeChange. Slot for handling count type change. + */ + void slotCountTypeChange(); + private slots: /** diff --git a/app/SysTray-X/systrayx.cpp b/app/SysTray-X/systrayx.cpp index 08ce593..a28914c 100644 --- a/app/SysTray-X/systrayx.cpp +++ b/app/SysTray-X/systrayx.cpp @@ -92,20 +92,18 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent ) connect( m_preferences, &Preferences::signalIconDataChange, m_pref_dialog, &PreferencesDialog::slotIconDataChange ); connect( m_preferences, &Preferences::signalShowNumberChange, m_pref_dialog, &PreferencesDialog::slotShowNumberChange ); connect( m_preferences, &Preferences::signalNumberColorChange, m_pref_dialog, &PreferencesDialog::slotNumberColorChange ); + connect( m_preferences, &Preferences::signalCountTypeChange, m_pref_dialog, &PreferencesDialog::slotCountTypeChange ); connect( m_preferences, &Preferences::signalMinimizeTypeChange, m_pref_dialog, &PreferencesDialog::slotMinimizeTypeChange ); connect( m_preferences, &Preferences::signalStartMinimizedChange, m_pref_dialog, &PreferencesDialog::slotStartMinimizedChange ); - connect( m_preferences, &Preferences::signalPollStartupDelayChange, m_pref_dialog, &PreferencesDialog::slotPollStartupDelayChange ); - connect( m_preferences, &Preferences::signalPollIntervalChange, m_pref_dialog, &PreferencesDialog::slotPollIntervalChange ); connect( m_preferences, &Preferences::signalDebugChange, m_pref_dialog, &PreferencesDialog::slotDebugChange ); connect( m_preferences, &Preferences::signalIconTypeChange, m_link, &SysTrayXLink::slotIconTypeChange ); connect( m_preferences, &Preferences::signalIconDataChange, m_link, &SysTrayXLink::slotIconDataChange ); connect( m_preferences, &Preferences::signalShowNumberChange, m_link, &SysTrayXLink::slotShowNumberChange ); connect( m_preferences, &Preferences::signalNumberColorChange, m_link, &SysTrayXLink::slotNumberColorChange ); + connect( m_preferences, &Preferences::signalCountTypeChange, m_link, &SysTrayXLink::slotCountTypeChange ); connect( m_preferences, &Preferences::signalMinimizeTypeChange, m_link, &SysTrayXLink::slotMinimizeTypeChange ); connect( m_preferences, &Preferences::signalStartMinimizedChange, m_link, &SysTrayXLink::slotStartMinimizedChange ); - connect( m_preferences, &Preferences::signalPollStartupDelayChange, m_link, &SysTrayXLink::slotPollStartupDelayChange ); - connect( m_preferences, &Preferences::signalPollIntervalChange, m_link, &SysTrayXLink::slotPollIntervalChange ); connect( m_preferences, &Preferences::signalDebugChange, m_link, &SysTrayXLink::slotDebugChange ); connect( m_preferences, &Preferences::signalDebugChange, m_debug, &DebugWidget::slotDebugChange ); diff --git a/app/SysTray-X/systrayxlink.cpp b/app/SysTray-X/systrayxlink.cpp index c7a3bd2..a20595f 100644 --- a/app/SysTray-X/systrayxlink.cpp +++ b/app/SysTray-X/systrayxlink.cpp @@ -473,6 +473,17 @@ void SysTrayXLink::DecodePreferences( const QJsonObject& pref ) m_pref->setNumberColor( number_color ); } + if( pref.contains( "countType" ) && pref[ "countType" ].isString() ) + { + Preferences::CountType count_type = static_cast< Preferences::CountType >( pref[ "countType" ].toString().toInt() ); + + /* + * Store the new icon type + */ + m_pref->setCountType( count_type ); + } + + if( pref.contains( "minimizeType" ) && pref[ "minimizeType" ].isString() ) { Preferences::MinimizeType minimize_type = static_cast< Preferences::MinimizeType >( pref[ "minimizeType" ].toString().toInt() ); @@ -493,26 +504,6 @@ void SysTrayXLink::DecodePreferences( const QJsonObject& pref ) m_pref->setStartMinimized( start_minimized ); } - if( pref.contains( "pollStartupDelay" ) && pref[ "pollStartupDelay" ].isString() ) - { - QString poll_startup_delay = pref[ "pollStartupDelay" ].toString(); - - /* - * Store the new start minimized state - */ - m_pref->setPollStartupDelay( poll_startup_delay.toInt() ); - } - - if( pref.contains( "pollInterval" ) && pref[ "pollInterval" ].isString() ) - { - QString poll_interval = pref[ "pollInterval" ].toString(); - - /* - * Store the new poll interval - */ - m_pref->setPollInterval( poll_interval.toInt() ); - } - if( pref.contains( "debug" ) && pref[ "debug" ].isString() ) { bool debug = pref[ "debug" ].toString() == "true"; @@ -535,8 +526,6 @@ void SysTrayXLink::EncodePreferences( const Preferences& pref ) */ QJsonObject prefObject; prefObject.insert("debug", QJsonValue::fromVariant( QString( pref.getDebug() ? "true" : "false" ) ) ); - prefObject.insert("pollStartupDelay", QJsonValue::fromVariant( QString::number( pref.getPollStartupDelay() ) ) ); - prefObject.insert("pollInterval", QJsonValue::fromVariant( QString::number( pref.getPollInterval() ) ) ); prefObject.insert("minimizeType", QJsonValue::fromVariant( QString::number( pref.getMinimizeType() ) ) ); prefObject.insert("startMinimized", QJsonValue::fromVariant( QString( pref.getStartMinimized() ? "true" : "false" ) ) ); prefObject.insert("iconType", QJsonValue::fromVariant( QString::number( pref.getIconType() ) ) ); @@ -544,6 +533,7 @@ void SysTrayXLink::EncodePreferences( const Preferences& pref ) prefObject.insert("icon", QJsonValue::fromVariant( QString( pref.getIconData().toBase64() ) ) ); prefObject.insert("showNumber", QJsonValue::fromVariant( QString( pref.getShowNumber() ? "true" : "false" ) ) ); prefObject.insert("numberColor", QJsonValue::fromVariant( QString( pref.getNumberColor() ) ) ); + prefObject.insert("countType", QJsonValue::fromVariant( QString::number( pref.getCountType() ) ) ); QJsonObject preferencesObject; preferencesObject.insert("preferences", prefObject ); @@ -588,30 +578,6 @@ void SysTrayXLink::slotDebugChange() } -/* - * Handle a poll startup delay change signal - */ -void SysTrayXLink::slotPollStartupDelayChange() -{ - if( m_pref->getAppPrefChanged() ) - { - sendPreferences(); - } -} - - -/* - * Handle a poll interval change signal - */ -void SysTrayXLink::slotPollIntervalChange() -{ - if( m_pref->getAppPrefChanged() ) - { - sendPreferences(); - } -} - - /* * Handle the minimize type change signal */ @@ -682,3 +648,15 @@ void SysTrayXLink::slotNumberColorChange() sendPreferences(); } } + + +/* + * Handle the count type change signal + */ +void SysTrayXLink::slotCountTypeChange() +{ + if( m_pref->getAppPrefChanged() ) + { + sendPreferences(); + } +} diff --git a/app/SysTray-X/systrayxlink.h b/app/SysTray-X/systrayxlink.h index 6a03388..85741b3 100644 --- a/app/SysTray-X/systrayxlink.h +++ b/app/SysTray-X/systrayxlink.h @@ -190,16 +190,6 @@ class SysTrayXLink : public QObject */ void slotDebugChange(); - /** - * @brief slotPollStartupDelayChange. Handle a change in poll startup delay. - */ - void slotPollStartupDelayChange(); - - /** - * @brief slotPollIntervalChange. Handle a change in poll interval. - */ - void slotPollIntervalChange(); - /** * @brief slotMinimizeTypeChange. Slot for handling minimize type change signals. */ @@ -230,6 +220,11 @@ class SysTrayXLink : public QObject */ void slotNumberColorChange(); + /** + * @brief slotCountTypeChange. Slot for handling count type change signals. + */ + void slotCountTypeChange(); + private slots: /** diff --git a/webext/background.html b/webext/background.html index 088805e..f4fb324 100644 --- a/webext/background.html +++ b/webext/background.html @@ -9,8 +9,6 @@

Background

Background HTML

-
-
diff --git a/webext/background.js b/webext/background.js index 54f6354..a79ee70 100644 --- a/webext/background.js +++ b/webext/background.js @@ -1,11 +1,6 @@ var SysTrayX = { startupState: undefined, - pollTiming: { - pollStartupDelay: "60", - pollInterval: "60", - }, - platformInfo: undefined, browserInfo: undefined, @@ -15,11 +10,11 @@ var SysTrayX = { SysTrayX.Messaging = { accounts: [], + countType: 0, + filtersExt: undefined, + filters: undefined, init: function () { - // Get the filters from the storage - SysTrayX.Messaging.getFilters(); - // Lookout for storage changes browser.storage.onChanged.addListener(SysTrayX.Messaging.storageChanged); @@ -38,35 +33,70 @@ SysTrayX.Messaging = { // Send preferences to app SysTrayX.Messaging.sendPreferences(); - // Start polling the accounts - window.setTimeout( - SysTrayX.Messaging.pollAccounts, - SysTrayX.pollTiming.pollStartupDelay * 1000 - ); + /* + // New mail listener (TB76+) + if (SysTrayX.browserInfo.majorVersion > 75) { + // + // Mixed results, forgets accounts?, double events? + // + browser.messages.onNewMailReceived.addListener( + SysTrayX.Messaging.newMail + ); + } + */ + + browser.folderChange.onUnreadMailChange.addListener(function (unread) { + console.debug("folderChangeListener: " + unread); + + SysTrayX.Messaging.unreadCb(unread); + }); + + // Set the count type in the folderChange listener + browser.folderChange.setCountType(Number(SysTrayX.Messaging.countType)); + + // Set the filters in the folderChange listener + browser.folderChange.setFilters(SysTrayX.Messaging.filtersExt); // Try to catch the window state browser.windows.onFocusChanged.addListener(SysTrayX.Window.focusChanged); }, + /* + newMail: async function (folder, messages) { + console.debug( + "New mail: " + folder.accountId + ", " + messages.messages.length + ); + + let unread = messages.messages.length; + while (messages.id) { + page = await browser.messages.continueList(messages.id); + + unread = unread + page.messages.length; + } + console.debug("Unread: " + unread); + }, + */ + // // Handle a storage change // storageChanged: function (changes, area) { // Get the new preferences - SysTrayX.Messaging.getFilters(); - if ("pollStartupDelay" in changes && changes["pollStartupDelay"].newValue) { - SysTrayX.pollTiming = { - ...SysTrayX.pollTiming, - pollStartupDelay: changes["pollStartupDelay"].newValue, - }; + if ("filtersExt" in changes && changes["filtersExt"].newValue) { + SysTrayX.Messaging.filtersExt = changes["filtersExt"].newValue; + + browser.folderChange.setFilters(SysTrayX.Messaging.filtersExt); } - if ("pollInterval" in changes && changes["pollInterval"].newValue) { - SysTrayX.pollTiming = { - ...SysTrayX.pollTiming, - pollInterval: changes["pollInterval"].newValue, - }; + if ("filters" in changes && changes["filters"].newValue) { + SysTrayX.Messaging.filters = changes["filters"].newValue; + } + + if ("countType" in changes && changes["countType"].newValue) { + SysTrayX.Messaging.countType = changes["countType"].newValue; + + browser.folderChange.setCountType(Number(SysTrayX.Messaging.countType)); } if ("addonprefchanged" in changes && changes["addonprefchanged"].newValue) { @@ -82,86 +112,6 @@ SysTrayX.Messaging = { } }, - // - // Poll the accounts - // - pollAccounts: function () { - // - // Get the unread nessages of the selected accounts - // - const filtersDiv = document.getElementById("filters"); - const filtersAttr = filtersDiv.getAttribute("data-filters"); - - if (filtersAttr !== "undefined") { - const filters = JSON.parse(filtersAttr); - - if (filters.length > 0) { - SysTrayX.Messaging.unReadMessages(filters).then( - SysTrayX.Messaging.unreadCb - ); - } else { - SysTrayX.Link.postSysTrayXMessage({ unreadMail: 0 }); - } - } else { - // Never saved anything, construct temporary filters - if (SysTrayX.Messaging.accounts.length > 0) { - // Construct inbox filters for all accounts - let filters = []; - SysTrayX.Messaging.accounts.forEach((account) => { - const inbox = account.folders.filter( - (folder) => folder.type == "inbox" - ); - - if (inbox.length > 0) { - filters.push({ - unread: true, - folder: inbox[0], - }); - } - }); - - // Store them in the background HTML - const filtersDiv = document.getElementById("filters"); - filtersDiv.setAttribute("data-filters", JSON.stringify(filters)); - - SysTrayX.Messaging.unReadMessages(filters).then( - SysTrayX.Messaging.unreadCb - ); - } else { - // No accounts, no mail - SysTrayX.Link.postSysTrayXMessage({ unreadMail: 0 }); - } - } - - // Next round... - window.setTimeout( - SysTrayX.Messaging.pollAccounts, - SysTrayX.pollTiming.pollInterval * 1000 - ); - }, - - // - // Use the messages API to get the unread messages (Promise) - // Be aware that the data is only avaiable inside the callback - // - unReadMessages: async function (filters) { - let unreadMessages = 0; - for (let i = 0; i < filters.length; ++i) { - let page = await browser.messages.query(filters[i]); - let unread = page.messages.length; - - while (page.id) { - page = await browser.messages.continueList(page.id); - - unread = unread + page.messages.length; - } - - unreadMessages = unreadMessages + unread; - } - - return unreadMessages; - }, - // // Callback for unReadMessages // @@ -191,8 +141,6 @@ SysTrayX.Messaging = { sendPreferences: function () { const getter = browser.storage.sync.get([ "debug", - "pollStartupDelay", - "pollInterval", "minimizeType", "startMinimized", "iconType", @@ -200,14 +148,13 @@ SysTrayX.Messaging = { "icon", "showNumber", "numberColor", + "countType", ]); getter.then(this.sendPreferencesStorage, this.onSendPreferecesStorageError); }, sendPreferencesStorage: function (result) { const debug = result.debug || "false"; - const pollStartupDelay = result.pollStartupDelay || "60"; - const pollInterval = result.pollInterval || "60"; const minimizeType = result.minimizeType || "1"; const startMinimized = result.startMinimized || "false"; const iconType = result.iconType || "0"; @@ -215,13 +162,12 @@ SysTrayX.Messaging = { const icon = result.icon || []; const showNumber = result.showNumber || "true"; const numberColor = result.numberColor || "#000000"; + const countType = result.countType || "0"; // Send it to the app SysTrayX.Link.postSysTrayXMessage({ preferences: { debug: debug, - pollStartupDelay: pollStartupDelay, - pollInterval: pollInterval, minimizeType: minimizeType, startMinimized: startMinimized, iconType: iconType, @@ -229,6 +175,7 @@ SysTrayX.Messaging = { icon: icon, showNumber: showNumber, numberColor: numberColor, + countType: countType, }, }); @@ -245,26 +192,6 @@ SysTrayX.Messaging = { console.log(`GetIcon Error: ${error}`); }, - // - // Get the filters from the storage - // - getFilters: function () { - const getter = browser.storage.sync.get("filters"); - getter.then(this.getFiltersStorage, this.onGetFiltersStorageError); - }, - - // - // Get the filters from the storage and - // make them available in the background HTML - // - getFiltersStorage: function (result) { - const filters = result.filters || undefined; - - // Store them in the background HTML - const filtersDiv = document.getElementById("filters"); - filtersDiv.setAttribute("data-filters", JSON.stringify(filters)); - }, - onGetAccountsStorageError: function (error) { console.log(`GetAccounts Error: ${error}`); }, @@ -348,6 +275,13 @@ SysTrayX.Link = { }); } + const countType = response["preferences"].countType; + if (countType) { + browser.storage.sync.set({ + countType: countType, + }); + } + const minimizeType = response["preferences"].minimizeType; if (minimizeType) { browser.storage.sync.set({ @@ -362,20 +296,6 @@ SysTrayX.Link = { }); } - const pollStartupDelay = response["preferences"].pollStartupDelay; - if (pollStartupDelay) { - browser.storage.sync.set({ - pollStartupDelay: pollStartupDelay, - }); - } - - const pollInterval = response["preferences"].pollInterval; - if (pollInterval) { - browser.storage.sync.set({ - pollInterval: pollInterval, - }); - } - const debug = response["preferences"].debug; if (debug) { browser.storage.sync.set({ @@ -408,9 +328,6 @@ async function start() { SysTrayX.startupState = state; - // Get the poll timing - SysTrayX.pollTiming = await getPollTiming(); - // Set platform SysTrayX.platformInfo = await browser.runtime .getPlatformInfo() @@ -430,6 +347,10 @@ async function start() { .getBrowserInfo() .then((info) => info); + const version = SysTrayX.browserInfo.version.split("."); + SysTrayX.browserInfo.majorVersion = version[0]; + SysTrayX.browserInfo.minorVersion = version[1]; + console.log("Browser: " + SysTrayX.browserInfo.name); console.log("Vendor: " + SysTrayX.browserInfo.vendor); console.log("Version: " + SysTrayX.browserInfo.version); @@ -454,6 +375,15 @@ async function start() { // Get all accounts SysTrayX.Messaging.accounts = await browser.accounts.list(); + // Get the extended filters + SysTrayX.Messaging.filtersExt = await getFiltersExt(); + + // Get the filters + SysTrayX.Messaging.filters = await getFilters(); + + // Get the count type + SysTrayX.Messaging.countType = await getCountType(); + // Setup the link first SysTrayX.Link.init(); diff --git a/webext/js/defaults.js b/webext/js/defaults.js index 285796c..211d3e8 100644 --- a/webext/js/defaults.js +++ b/webext/js/defaults.js @@ -15,11 +15,11 @@ async function getDefaultIcon() { const iconStored = await getIcon.then(getStoredIcon, onStoredIconError); if (!iconStored) { - const toDataURL = url => + const toDataURL = (url) => fetch(url) - .then(response => response.blob()) + .then((response) => response.blob()) .then( - blob => + (blob) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); @@ -30,11 +30,8 @@ async function getDefaultIcon() { // Convert image to storage param let { iconMime, iconBase64 } = await toDataURL("icons/blank-icon.png").then( - dataUrl => { - const data = dataUrl - .split(":") - .pop() - .split(","); + (dataUrl) => { + const data = dataUrl.split(":").pop().split(","); return { iconMime: data[0].split(";")[0], iconBase64: data[1] }; } ); @@ -42,7 +39,7 @@ async function getDefaultIcon() { // Store default icon (base64) browser.storage.sync.set({ iconMime: iconMime, - icon: iconBase64 + icon: iconBase64, }); // Store in HTML @@ -69,19 +66,49 @@ async function getStartupState() { } // -// Get poll timing +// Get filters // -async function getPollTiming() { - function getDelayAndInterval(result) { - return { pollStartupDelay: result.pollStartupDelay || "60", pollInterval: result.pollInterval || "60" }; +async function getFilters() { + function getFiltersCb(result) { + return result.filters || undefined; } - function onDelayAndIntervalError() { - return { pollStartupDelay: "60", pollInterval: "60" }; + function onFiltersError() { + return undefined; } - const getTiming = browser.storage.sync.get([ - "pollStartupDelay", - "pollInterval"]); - return await getTiming.then(getDelayAndInterval, onDelayAndIntervalError); + const getFilters = browser.storage.sync.get("filters"); + return await getFilters.then(getFiltersCb, onFiltersError); +} + +// +// Get extended filters +// +async function getFiltersExt() { + function getFiltersExtCb(result) { + return result.filtersExt || undefined; + } + + function onFiltersExtError() { + return undefined; + } + + const getFiltersExt = browser.storage.sync.get("filtersExt"); + return await getFiltersExt.then(getFiltersExtCb, onFiltersExtError); +} + +// +// Get count type +// +async function getCountType() { + function getCountTypeCb(result) { + return result.countType || "0"; + } + + function onCountTypeError() { + return undefined; + } + + const getCountType = browser.storage.sync.get("countType"); + return await getCountType.then(getCountTypeCb, onCountTypeError); } diff --git a/webext/js/folderChange.js b/webext/js/folderChange.js new file mode 100644 index 0000000..79b051e --- /dev/null +++ b/webext/js/folderChange.js @@ -0,0 +1,416 @@ +/* eslint-disable object-shorthand */ + +const Ci = Components.interfaces; + +// Get various parts of the WebExtension framework that we need. +var { ExtensionCommon } = ChromeUtils.import( + "resource://gre/modules/ExtensionCommon.jsm" +); + +// You probably already know what this does. +var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +var { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); +var { fixIterator } = ChromeUtils.import( + "resource:///modules/iteratorUtils.jsm" +); + +// ChromeUtils.import() works in experiments for core resource urls as it did +// in legacy add-ons. However, chrome:// urls that point to add-on resources no +// longer work, as the "chrome.manifest" file is no longer supported, which +// defined the root path for each add-on. Instead, ChromeUtils.import() needs +// a url generated by +// +// let url = context.extension.rootURI.resolve("path/to/file.jsm") +// +// Instead of taking the extension object from the context, you may generate +// the extension object from a given add-on ID as shown in the example below. +// This allows to import a JSM without context, for example inside another JSM. +// +var { ExtensionParent } = ChromeUtils.import( + "resource://gre/modules/ExtensionParent.jsm" +); +var extension = ExtensionParent.GlobalManager.getExtension( + "systray-x@Ximi1970" +); +var { folderChange } = ChromeUtils.import( + extension.rootURI.resolve("modules/folderChange.jsm") +); + +// This is the important part. It implements the functions and events defined in schema.json. +// The variable must have the same name you've been using so far, "myapi" in this case. +var folderChange = class extends ExtensionCommon.ExtensionAPI { + getAPI(context) { + console.log("folderChange module started"); + + // To be notified of the extension going away, call callOnClose with any object that has a + // close function, such as this one. + context.callOnClose(this); + + // + // Setup folder listener + // + SysTrayX.init(); + + return { + // Again, this key must have the same name. + folderChange: { + setCountType: async function (type) { + SysTrayX.setCountType(type); + }, + + setFilters: async function (filters) { + SysTrayX.setFilters(filters); + }, + + onUnreadMailChange: new ExtensionCommon.EventManager({ + context, + name: "folderChange.onUnreadMailChange", + // In this function we add listeners for any events we want to listen to, and return a + // function that removes those listeners. To have the event fire in your extension, + // call fire.async. + register(fire) { + function callback(event, unread) { + return fire.async(unread); + } + + SysTrayX.add(callback); + return function () { + SysTrayX.remove(callback); + }; + }, + }).api(), + }, + }; + } + + close() { + /* + * Remove the folder listener + */ + SysTrayX.shutdown(); + + // This function is called if the extension is disabled or removed, or Thunderbird closes. + // We registered it with callOnClose, above. + console.log("folderChange module closed"); + + // Unload the JSM we imported above. This will cause Thunderbird to forget about the JSM, and + // load it afresh next time `import` is called. (If you don't call `unload`, Thunderbird will + // remember this version of the module and continue to use it, even if your extension receives + // an update.) You should *always* unload JSMs provided by your extension. + Cu.unload(extension.getURL("modules/folderChange.jsm")); + } +}; + +// A helpful class for listening to windows opening and closing. +// (This file had a lowercase E in Thunderbird 65 and earlier.) +var { ExtensionSupport } = ChromeUtils.import( + "resource:///modules/ExtensionSupport.jsm" +); + +var SysTrayX = { + MESSAGE_COUNT_TYPE_UNREAD: 0, + MESSAGE_COUNT_TYPE_NEW: 1, + + countType: this.MESSAGE_COUNT_TYPE_UNREAD, + + initialized: false, + + accounts: undefined, + filters: undefined, + + currentMsgCount: null, + newMsgCount: null, + + callback: undefined, + + init: function () { + if (this.initialized) { + console.warn("Folder listener already initialized"); + return; + } + + console.log("Initializing folder listener"); + + // Get the mail accounts using MailServices + this.getAccounts(); + + // Start listener + MailServices.mailSession.AddFolderListener( + this.mailSessionListener, + this.mailSessionListener.notificationFlags + ); + + this.initialized = true; + }, + + shutdown: function () { + if (!this.initialized) { + return; + } + + log.log("Shutting down folder listener"); + + // Stop listener + MailServices.mailSession.RemoveFolderListener(this.mailSessionListener); + + this.initialized = false; + }, + + setCountType: function (type) { + console.debug("setCountType: " + type); + + if (type === 0) { + this.countType = this.MESSAGE_COUNT_TYPE_UNREAD; + } else if (type === 1) { + this.countType = this.MESSAGE_COUNT_TYPE_NEW; + } else console.log("Unknown count type: " + type); + + // Update count + this.updateMsgCountWithCb(); + }, + + setFilters: function (filters) { + this.filters = filters; + + // Update count + this.updateMsgCountWithCb(); + }, + + mailSessionListener: { + notificationFlags: + Ci.nsIFolderListener.propertyFlagChanged | + Ci.nsIFolderListener.boolPropertyChanged | + Ci.nsIFolderListener.intPropertyChanged, + + OnItemIntPropertyChanged(item, property, oldValue, newValue) { + // TotalUnreadMessages, BiffState (per server) + /* + console.debug( + "OnItemIntPropertyChanged " + + property + + " for folder " + + item.prettyName + + " was " + + oldValue + + " became " + + newValue + + " NEW MESSAGES=" + + item.getNumNewMessages(true) + ); + */ + this.onMsgCountChange(item, property, oldValue, newValue); + }, + + OnItemBoolPropertyChanged: function (item, property, oldValue, newValue) { + // NewMessages (per folder) + /* + console.debug( + "OnItemBoolPropertyChanged " + + property + + " for folder " + + item.prettyName + + " was " + + oldValue + + " became " + + newValue + + " NEW MESSAGES=" + + item.getNumNewMessages(true) + ); + */ + this.onMsgCountChange(item, property, oldValue, newValue); + }, + + OnItemPropertyFlagChanged: function (item, property, oldFlag, newFlag) { + /* + console.debug( + "OnItemPropertyFlagChanged" + + property + + " for " + + item + + " was " + + oldFlag + + " became " + + newFlag + ); + */ + this.onMsgCountChange(item, property, oldFlag, newFlag); + }, + + onMsgCountChange: function (item, property, oldValue, newValue) { + let msgCountType = SysTrayX.countType; + + let prop = property.toString(); + if ( + prop === "TotalUnreadMessages" && + msgCountType === SysTrayX.MESSAGE_COUNT_TYPE_UNREAD + ) { + SysTrayX.updateMsgCountWithCb(); + } else { + if ( + prop === "NewMessages" && + msgCountType === SysTrayX.MESSAGE_COUNT_TYPE_NEW + ) { + if (oldValue === true && newValue === false) { + // https://bugzilla.mozilla.org/show_bug.cgi?id=727460 + item.setNumNewMessages(0); + } + SysTrayX.updateMsgCountWithCb(); + } + } + }, + }, + + updateMsgCountWithCb(callback) { + if (callback === undefined || !callback) { + callback = function (currentMsgCount, newMsgCount) { + // default + // .updateIcon(newMsgCount); + console.debug("Update icon: " + newMsgCount); + + if (SysTrayX.callback) { + SysTrayX.callback("unread-changed", newMsgCount); + } + }; + } + + let msgCountType = SysTrayX.countType; + if (msgCountType === SysTrayX.MESSAGE_COUNT_TYPE_UNREAD) { + this.countMessages("UnreadMessages"); + } else if (msgCountType === SysTrayX.MESSAGE_COUNT_TYPE_NEW) { + this.countMessages("HasNewMessages"); + } else console.error("Unknown message count type: " + msgCountType); + + // currentMsgCount and newMsgCount may be integers or bool, which do + // also support comparison operations + callback.call(this, this.currentMsgCount, this.newMsgCount); + this.currentMsgCount = this.newMsgCount; + }, + + countMessages(countType) { + console.debug("countMessages: " + countType); + + this.newMsgCount = 0; + for (let accountServer of this.accounts) { + // if (accountServer.type === ACCOUNT_SERVER_TYPE_IM) { + // continue; + // } + + // if (excludedAccounts.indexOf(accountServer.key) >= 0) + // { + // continue; + // } + + this.applyToSubfolders( + accountServer.prettyName, + accountServer.rootFolder, + true, + function (folder) { + this.msgCountIterate(countType, accountServer.prettyName, folder); + } + ); + } + + console.debug("Total " + countType + " = " + this.newMsgCount); + }, + + applyToSubfolders(account, folder, recursive, fun) { + if (folder.hasSubFolders) { + let subFolders = folder.subFolders; + while (subFolders.hasMoreElements()) { + let subFolder = subFolders.getNext().QueryInterface(Ci.nsIMsgFolder); + if (recursive && subFolder.hasSubFolders) + this.applyToSubfoldersRecursive(account, subFolder, recursive, fun); + else fun.call(this, subFolder); + } + } + }, + + applyToSubfoldersRecursive(account, folder, recursive, fun) { + fun.call(this, folder); + this.applyToSubfolders(account, folder, recursive, fun); + }, + + msgCountIterate(type, account, folder) { + let count = false; + + if (SysTrayX.filters) { + const match = SysTrayX.filters.filter( + (filter) => + filter.folder.accountName === account && + filter.folder.name === folder.prettyName + ); + + count = match.length > 0 + } else { + count = folder.getFlag(Ci.nsMsgFolderFlags.Inbox); + } + + if (count) { + SysTrayX["add" + type](folder); + } + }, + + addUnreadMessages(folder) { + let folderUnreadMsgCount = folder["getNumUnread"](false); + + console.debug( + "folder: " + + folder.prettyName + + " folderUnreadMsgCount= " + + folderUnreadMsgCount + ); + + /* nsMsgDBFolder::GetNumUnread basically returns mNumUnreadMessages + + mNumPendingUnreadMessages, while mNumPendingUnreadMessages may get -1 + when updated from the cache. Which means getNumUnread might return -1. */ + if (folderUnreadMsgCount > 0) { + this.newMsgCount += folderUnreadMsgCount; + } + }, + + addHasNewMessages(folder) { + let folderNewMsgCount = folder.hasNewMessages; + + console.debug( + "folder: " + folder.prettyName + " hasNewMessages= " + folderNewMsgCount + ); + + this.newMsgCount = this.newMsgCount || folderNewMsgCount; + }, + + getAccounts() { + console.debug("getAccounts"); + + let accountServers = []; + for (let accountServer of fixIterator( + MailServices.accounts.accounts, + Ci.nsIMsgAccount + )) { + accountServers.push(accountServer.incomingServer); + } + + for (let i = 0, len = accountServers.length; i < len; ++i) { + console.debug( + "ACCOUNT: " + + accountServers[i].prettyName + + " type: " + + accountServers[i].type + + " key: " + + accountServers[i].key.toString() + ); + } + + // Store the accounts + this.accounts = accountServers; + }, + + add(callback) { + this.callback = callback; + }, + + remove(callback) { + this.callback = undefined; + }, +}; diff --git a/webext/js/options_accounts.js b/webext/js/options_accounts.js index 1d721a8..c978845 100644 --- a/webext/js/options_accounts.js +++ b/webext/js/options_accounts.js @@ -23,7 +23,7 @@ SysTrayX.Accounts = { * Callback for getAccounts */ getAccountsCb: function (mailAccount) { - function createFolderTree(folders) { + function createFolderTreePre74(accountName, folders) { let result = []; let level = { result }; @@ -35,8 +35,9 @@ SysTrayX.Accounts = { if (!r[name]) { r[name] = { result: [] }; r.result.push({ - name: folder.name, + accountName: accountName, accountId: folder.accountId, + name: folder.name, path: folder.path, subFolders: r[name].result, }); @@ -49,6 +50,22 @@ SysTrayX.Accounts = { return result; } + function createFolderTree(accountName, folders) { + function traverse(folders) { + if (!folders) { + return; + } + for (let f of folders) { + f.accountName = accountName; + traverse(f.subFolders); + } + } + + traverse(folders); + + return folders; + } + let accounts = new Object(); for (let i = 0; i < mailAccount.length; i++) { @@ -119,12 +136,20 @@ SysTrayX.Accounts = { ); typeLi.appendChild(typeText); - // Create a usable folder tree 0) { diff --git a/webext/js/options_mailform.js b/webext/js/options_mailform.js index 773cc0e..e69de29 100644 --- a/webext/js/options_mailform.js +++ b/webext/js/options_mailform.js @@ -1,15 +0,0 @@ -function pollStartupDelay(e) { -// console.debug("Startup: " + e.target.value); -} - -function pollInterval(e) { -// console.debug("Interval: " + e.target.value); -} - -document - .getElementById("pollStartupDelay") - .addEventListener("change", pollStartupDelay); - -document - .getElementById("pollInterval") - .addEventListener("change", pollInterval); diff --git a/webext/manifest.json b/webext/manifest.json index bb6c073..271bcfb 100644 --- a/webext/manifest.json +++ b/webext/manifest.json @@ -35,5 +35,22 @@ "options_ui": { "page": "options.html", "open_in_tab": true + }, + + "experiment_apis": { + "folderChange": { + "schema": "schema_folderchange.json", + "parent": { + "scopes": [ + "addon_parent" + ], + "paths": [ + [ + "folderChange" + ] + ], + "script": "js/folderChange.js" + } + } } } diff --git a/webext/modules/folderChange.jsm b/webext/modules/folderChange.jsm new file mode 100644 index 0000000..47a73d5 --- /dev/null +++ b/webext/modules/folderChange.jsm @@ -0,0 +1,6 @@ +var EXPORTED_SYMBOLS = ["folderChange"]; + +var folderChange = { +}; + +console.log("Loading folderChange.jsm"); diff --git a/webext/options.html b/webext/options.html index 6161783..1b5e2ce 100644 --- a/webext/options.html +++ b/webext/options.html @@ -125,6 +125,16 @@ + + + + + +
@@ -139,42 +149,6 @@

    - - - - - - - - - -
    - - - -
    - - - -
    diff --git a/webext/options.js b/webext/options.js index c8cd102..1c980cd 100644 --- a/webext/options.js +++ b/webext/options.js @@ -31,12 +31,21 @@ SysTrayX.SaveOptions = { }); let filters = []; + let filtersExt = []; checkedFolders.forEach((folder) => { - const mailFolder = JSON.parse(folder.value); + const mailFolderExt = JSON.parse(folder.value); + + filtersExt.push({ + unread: true, + folder: mailFolderExt, + }); filters.push({ unread: true, - folder: mailFolder, + folder: { + accountId: mailFolderExt.accountId, + path: mailFolderExt.path, + }, }); }); @@ -44,34 +53,20 @@ SysTrayX.SaveOptions = { const filtersDiv = document.getElementById("filters"); filtersDiv.setAttribute("data-filters", JSON.stringify(filters)); + // Store extended query filters + browser.storage.sync.set({ + filtersExt: filtersExt, + }); + // Store query filters browser.storage.sync.set({ filters: filters, }); - // - // Save poll startup delay state - // - const pollStartupDelay = document.querySelector( - 'input[name="pollStartupDelay"]' - ).value; - browser.storage.sync.set({ - pollStartupDelay: pollStartupDelay, - }); - - // - // Save poll interval state - // - const pollInterval = document.querySelector('input[name="pollInterval"]') - .value; - browser.storage.sync.set({ - pollInterval: pollInterval, - }); - // // Save debug state // - let debug = document.querySelector('input[name="debug"]').checked; + const debug = document.querySelector('input[name="debug"]').checked; browser.storage.sync.set({ debug: `${debug}`, }); @@ -91,7 +86,7 @@ SysTrayX.SaveOptions = { // // Save start minimized state // - let startMinimized = document.querySelector('input[name="startMinimized"]') + const startMinimized = document.querySelector('input[name="startMinimized"]') .checked; browser.storage.sync.set({ startMinimized: `${startMinimized}`, @@ -108,9 +103,9 @@ SysTrayX.SaveOptions = { iconType: iconType, }); - let iconDiv = document.getElementById("icon"); - let iconBase64 = iconDiv.getAttribute("data-icon"); - let iconMime = iconDiv.getAttribute("data-icon-mime"); + const iconDiv = document.getElementById("icon"); + const iconBase64 = iconDiv.getAttribute("data-icon"); + const iconMime = iconDiv.getAttribute("data-icon-mime"); // Store icon (base64) browser.storage.sync.set({ @@ -126,7 +121,7 @@ SysTrayX.SaveOptions = { // // Save enable number state // - let showNumber = document.querySelector('input[name="showNumber"]').checked; + const showNumber = document.querySelector('input[name="showNumber"]').checked; browser.storage.sync.set({ showNumber: `${showNumber}`, }); @@ -134,10 +129,19 @@ SysTrayX.SaveOptions = { // // Save number color // - let numberColor = document.querySelector('input[name="numberColor"]').value; + const numberColor = document.querySelector('input[name="numberColor"]').value; browser.storage.sync.set({ numberColor: `${numberColor}`, }); + + // + // Save count type preferences + // + const countType = document.querySelector('input[name="countType"]:checked') + .value; + browser.storage.sync.set({ + countType: countType, + }); }, }; @@ -200,24 +204,6 @@ SysTrayX.RestoreOptions = { SysTrayX.RestoreOptions.onFiltersError ); - // - // Restore poll startup delay state - // - const getPollStartupDelay = browser.storage.sync.get("pollStartupDelay"); - getPollStartupDelay.then( - SysTrayX.RestoreOptions.setPollStartupDelay, - SysTrayX.RestoreOptions.onPollStartupDelayError - ); - - // - // Restore poll interval state - // - const getPollInterval = browser.storage.sync.get("pollInterval"); - getPollInterval.then( - SysTrayX.RestoreOptions.setPollInterval, - SysTrayX.RestoreOptions.onPollIntervalError - ); - // // Restore enable number state // @@ -235,6 +221,15 @@ SysTrayX.RestoreOptions = { SysTrayX.RestoreOptions.setNumberColor, SysTrayX.RestoreOptions.onNumberColorError ); + + // + // Restore count type + // + const getCountType = browser.storage.sync.get("countType"); + getCountType.then( + SysTrayX.RestoreOptions.setCountType, + SysTrayX.RestoreOptions.onCountTypeError + ); }, // @@ -387,6 +382,22 @@ SysTrayX.RestoreOptions = { console.log(`numberColor Error: ${error}`); }, + // + // Restore count type + // + setCountType: function (result) { + const countType = result.countType || "0"; + + const radioButton = document.querySelector( + `input[name="countType"][value="${countType}"]` + ); + radioButton.checked = true; + }, + + onCountTypeError: function (error) { + console.log(`countType Error: ${error}`); + }, + // // Restore filters callbacks // @@ -459,34 +470,6 @@ SysTrayX.RestoreOptions = { onFiltersError: function (error) { console.log(`Filters Error: ${error}`); }, - - // - // Restore poll startup delay state callbacks - // - setPollStartupDelay: function (result) { - const pollStartupDelay = result.pollStartupDelay || 60; - - const input = document.querySelector(`input[name="pollStartupDelay"]`); - input.value = pollStartupDelay; - }, - - onPollStartupDelayError: function (error) { - console.log(`Poll startup delay Error: ${error}`); - }, - - // - // Restore poll interval state callbacks - // - setPollInterval: function (result) { - const pollInterval = result.pollInterval || 60; - - const input = document.querySelector(`input[name="pollInterval"]`); - input.value = pollInterval; - }, - - onPollPollInterval: function (error) { - console.log(`Poll interval Error: ${error}`); - }, }; SysTrayX.StorageChanged = { @@ -522,6 +505,11 @@ SysTrayX.StorageChanged = { numberColor: changes[item].newValue, }); } + if (item === "countType") { + SysTrayX.RestoreOptions.setCountType({ + countType: changes[item].newValue, + }); + } if (item === "minimizeType") { SysTrayX.RestoreOptions.setMinimizeType({ minimizeType: changes[item].newValue, @@ -532,16 +520,6 @@ SysTrayX.StorageChanged = { startMinimized: changes[item].newValue, }); } - if (item === "pollStartupDelay") { - SysTrayX.RestoreOptions.setPollStartupDelay({ - pollStartupDelay: changes[item].newValue, - }); - } - if (item === "pollInterval") { - SysTrayX.RestoreOptions.setPollInterval({ - pollInterval: changes[item].newValue, - }); - } if (item === "debug") { SysTrayX.RestoreOptions.setDebug({ debug: changes[item].newValue, diff --git a/webext/schema_folderchange.json b/webext/schema_folderchange.json new file mode 100644 index 0000000..94d8cf3 --- /dev/null +++ b/webext/schema_folderchange.json @@ -0,0 +1,71 @@ +[ + { + "namespace": "folderChange", + "functions": [ + { + "name": "setCountType", + "type": "function", + "description": "Set the count type.", + "async": true, + "parameters": [ + { + "type": "integer", + "name": "type", + "minimum": 0, + "maximum": 1 + } + ] + }, + { + "name": "setFilters", + "type": "function", + "description": "Set the account filters.", + "async": true, + "parameters": [ + { + "name": "filters", + "type": "array", + "items": { + "type": "object", + "properties": { + "unread": { + "type": "boolean" + }, + "folder": { + "type": "object", + "properties": { + "accountName": { + "type": "string" + }, + "accountId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + } + } + } + } + } + } + ] + } + ], + "events": [ + { + "name": "onUnreadMailChange", + "type": "function", + "description": "Fires when there is a change in the number of unread mails.", + "parameters": [ + { + "name": "unread", + "type": "integer" + } + ] + } + ] + } +]