Merge branch 'feature-unread' into feature-experiment-api

This commit is contained in:
Ximi1970
2020-05-10 21:06:08 +02:00
19 changed files with 1055 additions and 740 deletions

View File

@@ -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.
*/

View File

@@ -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.
*/

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>583</width>
<height>261</height>
<width>482</width>
<height>442</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,207 +17,10 @@
<iconset resource="SysTray-X.qrc">
<normaloff>:/files/icons/SysTray-X.png</normaloff>:/files/icons/SysTray-X.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="1" rowspan="2" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Number properties</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QCheckBox" name="showNumberCheckBox">
<property name="text">
<string>Display unread message count</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Text color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="numberColorPushButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Mail actions</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="pollStartupDelayLabel">
<property name="text">
<string>Poll startup delay</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="pollStartupDelaySpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
<property name="value">
<number>60</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="pollIntervalLabel">
<property name="text">
<string>Poll interval</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="pollIntervalSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>999</number>
</property>
<property name="value">
<number>60</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Windows</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Minimize</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="defaultMinimizeRadioButton">
<property name="text">
<string>Default minimize</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">minimizeTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="minimizeMethod1RadioButton">
<property name="text">
<string>Minimize to tray, method 1</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">minimizeTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="minimizeMethod2RadioButton">
<property name="text">
<string>Minimize to tray, method 2</string>
</property>
<attribute name="buttonGroup">
<string notr="true">minimizeTypeGroup</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="startMinimizedCheckBox">
<property name="text">
<string>Start application minimized</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QGroupBox" name="iconTypeGroupBox">
<property name="title">
<string>Mail notification icon</string>
@@ -327,7 +130,100 @@
</layout>
</widget>
</item>
<item row="2" column="0">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Number properties</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QCheckBox" name="showNumberCheckBox">
<property name="text">
<string>Display unread message count</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Text color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="numberColorPushButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="countTypeGroupBox">
<property name="title">
<string>Count type</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QRadioButton" name="unreadRadioButton">
<property name="text">
<string>Unread</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">countTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="newRadioButton">
<property name="text">
<string>New</string>
</property>
<attribute name="buttonGroup">
<string notr="true">countTypeGroup</string>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="debugWindowCheckBox">
<property name="text">
<string>Display debug window</string>
@@ -336,7 +232,89 @@
</item>
</layout>
</item>
<item row="1" column="0">
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Windows</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Minimize</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="defaultMinimizeRadioButton">
<property name="text">
<string>Default minimize</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">minimizeTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="minimizeMethod1RadioButton">
<property name="text">
<string>Minimize to tray, method 1</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">minimizeTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="minimizeMethod2RadioButton">
<property name="text">
<string>Minimize to tray, method 2</string>
</property>
<attribute name="buttonGroup">
<string notr="true">minimizeTypeGroup</string>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="startMinimizedCheckBox">
<property name="text">
<string>Start application minimized</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>197</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -370,7 +348,8 @@
</connection>
</connections>
<buttongroups>
<buttongroup name="iconTypeGroup"/>
<buttongroup name="minimizeTypeGroup"/>
<buttongroup name="countTypeGroup"/>
<buttongroup name="iconTypeGroup"/>
</buttongroups>
</ui>

View File

@@ -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() );
}

View File

@@ -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:
/**

View File

@@ -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 );

View File

@@ -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();
}
}

View File

@@ -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:
/**

View File

@@ -9,8 +9,6 @@
<h3>Background</h3>
<p>Background HTML</p>
<div id="filters" data-filters="undefined"></div>
<script src="js/defaults.js"></script>
<div id="icon" data-icon-mime="" data-icon=""></div>

View File

@@ -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();

View File

@@ -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);
}

416
webext/js/folderChange.js Normal file
View File

@@ -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;
},
};

View File

@@ -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 <TB74
// Create a usable folder tree
let folders = [];
if (BrowserInfo.version.split(".")[0] < 74) {
folders = createFolderTree(accounts[prop][i].folders);
// Pre TB74 accounts API
folders = createFolderTreePre74(
accounts[prop][i].name,
accounts[prop][i].folders
);
} else {
folders = accounts[prop][i].folders;
// TB74+ accounts API, (this shit never ends...)
folders = createFolderTree(
accounts[prop][i].name,
accounts[prop][i].folders
);
}
// Recursive list creator
@@ -155,8 +180,10 @@ SysTrayX.Accounts = {
typeEleInput.setAttribute(
"value",
JSON.stringify({
accountName: element.accountName,
accountId: element.accountId,
path: element.path,
name: element.name,
})
);
if (element.subFolders.length > 0) {

View File

@@ -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);

View File

@@ -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"
}
}
}
}

View File

@@ -0,0 +1,6 @@
var EXPORTED_SYMBOLS = ["folderChange"];
var folderChange = {
};
console.log("Loading folderChange.jsm");

View File

@@ -125,6 +125,16 @@
</td>
</tr>
</table>
<table id="countprops" style="display:none">
<tr>
<td>
<label for="countType">Message count type: </label>
<input type="radio" name="countType" value="0" /> Unread
<input type="radio" name="countType" value="1" /> New
</td>
</tr>
</table>
</form>
<div id="icon" data-icon-mime="" data-icon=""></div>
@@ -139,42 +149,6 @@
<ul id="accountsTree"></ul>
<br />
<table id="pollselect">
<tr>
<td>
<label for="pollStartupDelay" }>Poll startup delay</label>
</td>
<td>
<input
type="number"
id="pollStartupDelay"
name="pollStartupDelay"
step="1"
min="1"
max="999"
value="60"
style="width: 4em;"
/>
</td>
</tr>
<tr>
<td>
<label for="pollInterval" }>Poll interval</label>
</td>
<td>
<input
type="number"
id="pollInterval"
name="pollInterval"
step="1"
min="1"
max="999"
value="60"
style="width: 4em;"
/>
</td>
</tr>
</table>
</form>
<div id="filters" data-filters="undefined"></div>

View File

@@ -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,

View File

@@ -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"
}
]
}
]
}
]