Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/betaflight/betaflight-configurator.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ Blackman <blckmn@users.noreply.github.com>2022-10-17 23:35:01 +0300
committerGitHub <noreply@github.com>2022-10-17 23:35:01 +0300
commitd930924b2bb53edd2eed5934388b8fb9e0a32c98 (patch)
treea4cc8c50dece26695d4125ef73447e744dac38fd
parent83cbb79ed741ca7595d5e07878bc232e86a571b4 (diff)
parent152e1e9100b6803320d96e37fdce975318a6f8c2 (diff)
Merge pull request #3052 from limonspb/fav_presets
Presets: Interactive stars for favorites
-rw-r--r--src/images/icons/star_orange.svg6
-rw-r--r--src/images/icons/star_orange_stroke.svg6
-rw-r--r--src/images/icons/star_transparent.svg6
-rw-r--r--src/tabs/presets/DetailedDialog/PresetsDetailedDialog.js6
-rw-r--r--src/tabs/presets/FavoritePresets.js15
-rw-r--r--src/tabs/presets/TitlePanel/PresetTitlePanel.css18
-rw-r--r--src/tabs/presets/TitlePanel/PresetTitlePanel.js88
-rw-r--r--src/tabs/presets/TitlePanel/PresetTitlePanelBody.html1
-rw-r--r--src/tabs/presets/presets.js4
9 files changed, 134 insertions, 16 deletions
diff --git a/src/images/icons/star_orange.svg b/src/images/icons/star_orange.svg
new file mode 100644
index 00000000..7be1447a
--- /dev/null
+++ b/src/images/icons/star_orange.svg
@@ -0,0 +1,6 @@
+<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
+ <g id="Layer_1">
+ <title>Layer 1</title>
+ <path stroke="#ffbb00" stroke-width="2" id="svg_1" d="m3.08281,39.47823l35.8418,0l11.07539,-34.04956l11.0754,34.04956l35.84179,0l-28.99657,21.04355l11.07596,34.04956l-28.99658,-21.04412l-28.99658,21.04412l11.07597,-34.04956l-28.99658,-21.04355z" fill="#ffbb00"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/src/images/icons/star_orange_stroke.svg b/src/images/icons/star_orange_stroke.svg
new file mode 100644
index 00000000..71fe5fe7
--- /dev/null
+++ b/src/images/icons/star_orange_stroke.svg
@@ -0,0 +1,6 @@
+<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
+ <g id="Layer_1">
+ <title>Layer 1</title>
+ <path stroke="#ffbb00" stroke-width="2" id="svg_1" d="m3.08281,39.47823l35.8418,0l11.07539,-34.04956l11.0754,34.04956l35.84179,0l-28.99657,21.04355l11.07596,34.04956l-28.99658,-21.04412l-28.99658,21.04412l11.07597,-34.04956l-28.99658,-21.04355z" fill="none"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/src/images/icons/star_transparent.svg b/src/images/icons/star_transparent.svg
new file mode 100644
index 00000000..a1b233d5
--- /dev/null
+++ b/src/images/icons/star_transparent.svg
@@ -0,0 +1,6 @@
+<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
+ <g id="Layer_1">
+ <title>Layer 1</title>
+ <path stroke="#9c9c9c" stroke-width="2" id="svg_1" d="m3.08281,39.47823l35.8418,0l11.07539,-34.04956l11.0754,34.04956l35.84179,0l-28.99657,21.04355l11.07596,34.04956l-28.99658,-21.04412l-28.99658,21.04412l11.07597,-34.04956l-28.99658,-21.04355z" fill="none"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/src/tabs/presets/DetailedDialog/PresetsDetailedDialog.js b/src/tabs/presets/DetailedDialog/PresetsDetailedDialog.js
index 9f110bf1..cbf4e075 100644
--- a/src/tabs/presets/DetailedDialog/PresetsDetailedDialog.js
+++ b/src/tabs/presets/DetailedDialog/PresetsDetailedDialog.js
@@ -1,13 +1,14 @@
'use strict';
class PresetsDetailedDialog {
- constructor(domDialog, pickedPresetList, onPresetPickedCallback) {
+ constructor(domDialog, pickedPresetList, onPresetPickedCallback, favoritePresets) {
this._domDialog = domDialog;
this._pickedPresetList = pickedPresetList;
this._finalDialogYesNoSettings = {};
this._onPresetPickedCallback = onPresetPickedCallback;
this._openPromiseResolve = undefined;
this._isDescriptionHtml = false;
+ this._favoritePresets = favoritePresets;
}
load() {
@@ -71,7 +72,8 @@ class PresetsDetailedDialog {
}
this._titlePanel.empty();
- const titlePanel = new PresetTitlePanel(this._titlePanel, this._preset, false, () => this._setLoadingState(false));
+ const titlePanel = new PresetTitlePanel(this._titlePanel, this._preset, false,
+ () => this._setLoadingState(false), this._favoritePresets);
titlePanel.load();
this._loadOptionsSelect();
this._updateFinalCliText();
diff --git a/src/tabs/presets/FavoritePresets.js b/src/tabs/presets/FavoritePresets.js
index f5799ba5..9693d7d5 100644
--- a/src/tabs/presets/FavoritePresets.js
+++ b/src/tabs/presets/FavoritePresets.js
@@ -53,6 +53,16 @@ class FavoritePresetsData {
return preset;
}
+ delete(presetPath) {
+ const index = this._favoritePresetsList.findIndex((preset) => preset.presetPath === presetPath);
+
+ if (index >= 0) {
+ this._favoritePresetsList.splice(index, 1);
+ this._sort();
+ this._purgeOldPresets();
+ }
+ }
+
findPreset(presetPath) {
return this._favoritePresetsList.find((preset) => preset.presetPath === presetPath);
}
@@ -69,6 +79,11 @@ class FavoritePresetsClass {
preset.lastPickDate = favoritePreset.lastPickDate;
}
+ delete(preset) {
+ this._favoritePresetsData.delete(preset.fullPath);
+ preset.lastPickDate = undefined;
+ }
+
addLastPickDate(presets) {
for (let preset of presets) {
let favoritePreset = this._favoritePresetsData.findPreset(preset.fullPath);
diff --git a/src/tabs/presets/TitlePanel/PresetTitlePanel.css b/src/tabs/presets/TitlePanel/PresetTitlePanel.css
index bdd086d6..e9481d12 100644
--- a/src/tabs/presets/TitlePanel/PresetTitlePanel.css
+++ b/src/tabs/presets/TitlePanel/PresetTitlePanel.css
@@ -1,5 +1,6 @@
.preset_title_panel {
color: var(--defaultText);
+ position: relative;
}
.preset_title_panel_border {
@@ -14,11 +15,26 @@
.preset_title_panel_title {
font-size: 1.5em;
font-weight: bold;
- display: block;
+ display: inline-block;
margin-bottom: 1ex;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
+ width: calc(100% - 30px);
+}
+
+.preset_title_panel_star {
+ background-image: url(../../../images/icons/star_orange.svg);
+ width: 25px;
+ height: 25px;
+ background-size: cover;
+ border-radius: 5px;
+ padding: 5px;
+ background-origin: content-box;
+ background-repeat: no-repeat;
+ position: absolute;
+ right: -6px;
+ top: -5px;
}
.preset_title_panel_category {
diff --git a/src/tabs/presets/TitlePanel/PresetTitlePanel.js b/src/tabs/presets/TitlePanel/PresetTitlePanel.js
index ec2b66f5..8c49760d 100644
--- a/src/tabs/presets/TitlePanel/PresetTitlePanel.js
+++ b/src/tabs/presets/TitlePanel/PresetTitlePanel.js
@@ -2,7 +2,7 @@
class PresetTitlePanel
{
- constructor(parentDiv, preset, clickable, onLoadedCallback)
+ constructor(parentDiv, preset, clickable, onLoadedCallback, favoritePresets)
{
PresetTitlePanel.s_panelCounter ++;
this._parentDiv = parentDiv;
@@ -10,16 +10,45 @@ class PresetTitlePanel
this._domId = `preset_title_panel_${PresetTitlePanel.s_panelCounter}`;
this._preset = preset;
this._clickable = clickable;
+ this._favoritePresets = favoritePresets;
this._parentDiv.append(`<div class="${this._domId}"></div>`);
this._domWrapperDiv = $(`.${this._domId}`);
this._domWrapperDiv.toggle(false);
+ this._starJustClicked = false;
+ this._mouseOnStar = false;
+ this._mouseOnPanel = false;
+ this._clickable = clickable;
if (clickable) {
this._domWrapperDiv.addClass("preset_title_panel_border");
// setting up hover effect here, because if setup in SCC it stops working after background animation like - this._domWrapperDiv.animate({ backgroundColor....
- this._domWrapperDiv.on("mouseenter", () => this._domWrapperDiv.css({"background-color": "var(--subtleAccent)"}));
- this._domWrapperDiv.on("mouseleave", () => this._domWrapperDiv.css({"background-color": "var(--boxBackground)"}));
+ }
+ }
+
+ _updateHoverEffects() {
+ let starMouseHover = false;
+
+ if (this._clickable && this._mouseOnPanel && !this._mouseOnStar) {
+ this._domWrapperDiv.css({"background-color": "var(--subtleAccent)"});
+ } else {
+ this._domWrapperDiv.css({"background-color": "var(--boxBackground)"});
+ }
+
+ if (this._mouseOnStar || (this._mouseOnPanel && this._clickable)) {
+ this._domStar.css({"background-color": "var(--subtleAccent)"});
+ starMouseHover = true;
+ } else {
+ this._domWrapperDiv.css({"background-color": "var(--boxBackground)"});
+ this._domStar.css({"background-color": "var(--boxBackground)"});
+ }
+
+ if (this._preset.lastPickDate) {
+ this._domStar.css("background-image", "url('../../../images/icons/star_orange.svg')");
+ } else if (starMouseHover) {
+ this._domStar.css("background-image", "url('../../../images/icons/star_orange_stroke.svg')");
+ } else {
+ this._domStar.css("background-image", "url('../../../images/icons/star_transparent.svg')");
}
}
@@ -30,14 +59,24 @@ class PresetTitlePanel
subscribeClick(presetsDetailedDialog, presetsRepo)
{
this._domWrapperDiv.on("click", () => {
- presetsDetailedDialog.open(this._preset, presetsRepo).then(isPresetPicked => {
- if (isPresetPicked) {
- const color = this._domWrapperDiv.css( "background-color" );
- this._domWrapperDiv.css('background-color', 'green');
- this._domWrapperDiv.animate({ backgroundColor: color }, 2000);
- this.setPicked(true);
- }
- });
+ if (!this._starJustClicked) {
+ this._showPresetsDetailedDialog(presetsDetailedDialog, presetsRepo);
+ }
+
+ this._starJustClicked = false;
+ });
+ }
+
+ _showPresetsDetailedDialog(presetsDetailedDialog, presetsRepo) {
+ presetsDetailedDialog.open(this._preset, presetsRepo).then(isPresetPicked => {
+ if (isPresetPicked) {
+ const color = this._domWrapperDiv.css( "background-color" );
+ this._domWrapperDiv.css('background-color', 'green');
+ this._domWrapperDiv.animate({ backgroundColor: color }, 2000);
+ this.setPicked(true);
+ }
+
+ this._updateHoverEffects();
});
}
@@ -70,6 +109,12 @@ class PresetTitlePanel
this._domStatusCommunity.toggle(this._preset.status === "COMMUNITY");
this._domStatusExperimental.toggle(this._preset.status === "EXPERIMENTAL");
this.setPicked(this._preset.isPicked);
+ this._setupStar();
+
+ this._domWrapperDiv.on("mouseenter", () => { this._mouseOnPanel = true; this._updateHoverEffects(); });
+ this._domWrapperDiv.on("mouseleave", () => { this._mouseOnPanel = false; this._updateHoverEffects(); } );
+ this._domStar.on("mouseenter", () => { this._mouseOnStar = true; this._updateHoverEffects(); });
+ this._domStar.on("mouseleave", () => { this._mouseOnStar = false; this._updateHoverEffects(); });
i18n.localizePage();
this._domWrapperDiv.toggle(true);
@@ -79,6 +124,7 @@ class PresetTitlePanel
_readDom()
{
this._domTitle = this._domWrapperDiv.find('.preset_title_panel_title');
+ this._domStar = this._domWrapperDiv.find('.preset_title_panel_star');
this._domCategory = this._domWrapperDiv.find('.preset_title_panel_category');
this._domAuthor = this._domWrapperDiv.find('.preset_title_panel_author_text');
this._domKeywords = this._domWrapperDiv.find('.preset_title_panel_keywords_text');
@@ -88,6 +134,26 @@ class PresetTitlePanel
this._domStatusExperimental = this._domWrapperDiv.find('.preset_title_panel_status_experimental');
}
+ _setupStar() {
+ this._updateHoverEffects();
+
+ this._domStar.on("click", () => {
+ this._starJustClicked = true;
+ this._processStarClick();
+ });
+ }
+
+ _processStarClick() {
+ if (this._preset.lastPickDate) {
+ this._favoritePresets.delete(this._preset);
+ } else {
+ this._favoritePresets.add(this._preset);
+ }
+
+ this._favoritePresets.saveToStorage();
+ this._updateHoverEffects();
+ }
+
remove()
{
this._domWrapperDiv.remove();
diff --git a/src/tabs/presets/TitlePanel/PresetTitlePanelBody.html b/src/tabs/presets/TitlePanel/PresetTitlePanelBody.html
index 081c53eb..7dd031ba 100644
--- a/src/tabs/presets/TitlePanel/PresetTitlePanelBody.html
+++ b/src/tabs/presets/TitlePanel/PresetTitlePanelBody.html
@@ -1,4 +1,5 @@
<div class="preset_title_panel">
+ <span class="preset_title_panel_star"></span>
<div>
<span class="preset_title_panel_title"></span>
</div>
diff --git a/src/tabs/presets/presets.js b/src/tabs/presets/presets.js
index f5e89656..fd7936e7 100644
--- a/src/tabs/presets/presets.js
+++ b/src/tabs/presets/presets.js
@@ -269,7 +269,7 @@ presets.onHtmlLoad = function(callback) {
this.setupBackupWarning();
this._inputTextFilter.attr("placeholder", "example: \"karate race\", or \"5'' freestyle\"");
- this.presetsDetailedDialog = new PresetsDetailedDialog($("#presets_detailed_dialog"), this.pickedPresetList, () => this.onPresetPickedCallback());
+ this.presetsDetailedDialog = new PresetsDetailedDialog($("#presets_detailed_dialog"), this.pickedPresetList, () => this.onPresetPickedCallback(), favoritePresets);
this.presetsSourcesDialog = new PresetsSourcesDialog($("#presets_sources_dialog"));
this.presetsDetailedDialog.load()
@@ -460,7 +460,7 @@ presets.displayPresets = function(fitPresets) {
this._domListNoFound.toggle(fitPresets.length === 0);
fitPresets.forEach(preset => {
- const presetPanel = new PresetTitlePanel(this._divPresetList, preset, true);
+ const presetPanel = new PresetTitlePanel(this._divPresetList, preset, true, undefined, favoritePresets);
presetPanel.load();
this._presetPanels.push(presetPanel);
presetPanel.subscribeClick(this.presetsDetailedDialog, this.presetsRepo);