From a021ba87fa544cf735d6e8d97c1f72afceb44f62 Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Tue, 16 May 2023 23:01:32 +0200 Subject: [PATCH] UI - New "Search List" icon and functionality (#1580) --- changedetectionio/__init__.py | 16 +++++- changedetectionio/static/js/toggle-theme.js | 31 ++++++++++- .../static/styles/scss/styles.scss | 55 ++++++++++++++----- changedetectionio/static/styles/styles.css | 43 +++++++++++---- changedetectionio/store.py | 6 +- .../templates/_common_fields.jinja | 2 +- changedetectionio/templates/base.html | 12 +++- .../templates/svgs/search-icon.svg | 1 + .../templates/watch-overview.html | 7 ++- 9 files changed, 139 insertions(+), 34 deletions(-) create mode 100644 changedetectionio/templates/svgs/search-icon.svg diff --git a/changedetectionio/__init__.py b/changedetectionio/__init__.py index 1afddfd1..5c04c9fa 100644 --- a/changedetectionio/__init__.py +++ b/changedetectionio/__init__.py @@ -403,6 +403,7 @@ def changedetection_app(config=None, datastore_o=None): # Sort by last_changed and add the uuid which is usually the key.. sorted_watches = [] + search_q = request.args.get('q').strip().lower() if request.args.get('q') else False for uuid, watch in datastore.data['watching'].items(): if limit_tag != None: @@ -413,16 +414,24 @@ def changedetection_app(config=None, datastore_o=None): tag_in_watch = tag_in_watch.strip() if tag_in_watch == limit_tag: watch['uuid'] = uuid - sorted_watches.append(watch) + if search_q: + if (watch.get('title') and search_q in watch.get('title')) or search_q in watch.get('url', '').lower(): + sorted_watches.append(watch) + else: + sorted_watches.append(watch) else: watch['uuid'] = uuid - sorted_watches.append(watch) + if search_q: + if (watch.get('title') and search_q in watch.get('title')) or search_q in watch.get('url', '').lower(): + sorted_watches.append(watch) + else: + sorted_watches.append(watch) existing_tags = datastore.get_all_tags() form = forms.quickWatchForm(request.form) page = request.args.get(get_page_parameter(), type=int, default=1) - total_count = len(sorted_watches) if sorted_watches else len(datastore.data['watching']) + total_count = len(sorted_watches) pagination = Pagination(page=page, total=total_count, per_page=int(os.getenv('pagination_per_page', 50)), css_framework = "semantic") output = render_template( @@ -437,6 +446,7 @@ def changedetection_app(config=None, datastore_o=None): hosted_sticky=os.getenv("SALTED_PASS", False) == False, pagination=pagination, queued_uuids=[q_uuid.item['uuid'] for q_uuid in update_q.queue], + search_q=request.args.get('q','').strip(), sort_attribute=request.args.get('sort') if request.args.get('sort') else request.cookies.get('sort'), sort_order=request.args.get('order') if request.args.get('order') else request.cookies.get('order'), system_default_fetcher=datastore.data['settings']['application'].get('fetch_backend'), diff --git a/changedetectionio/static/js/toggle-theme.js b/changedetectionio/static/js/toggle-theme.js index ca11ec99..218fdd0c 100644 --- a/changedetectionio/static/js/toggle-theme.js +++ b/changedetectionio/static/js/toggle-theme.js @@ -3,7 +3,7 @@ * Toggles theme between light and dark mode. */ $(document).ready(function () { - const button = document.getElementsByClassName("toggle-theme")[0]; + const button = document.getElementById("toggle-light-mode"); button.onclick = () => { const htmlElement = document.getElementsByTagName("html"); @@ -21,4 +21,33 @@ $(document).ready(function () { const setCookieValue = (value) => { document.cookie = `css_dark_mode=${value};max-age=31536000;path=/` } + + // Search input box behaviour + const toggle_search = document.getElementById("toggle-search"); + const search_q = document.getElementById("search-q"); + window.addEventListener('keydown', function (e) { + + if (e.altKey == true && e.keyCode == 83) + search_q.classList.toggle('expanded'); + search_q.focus(); + }); + + + search_q.onkeydown = (e) => { + var key = e.keyCode || e.which; + if (key === 13) { + document.searchForm.submit(); + } + }; + toggle_search.onclick = () => { + // Could be that they want to search something once text is in there + if (search_q.value.length) { + document.searchForm.submit(); + } else { + // If not.. + search_q.classList.toggle('expanded'); + search_q.focus(); + } + }; + }); diff --git a/changedetectionio/static/styles/scss/styles.scss b/changedetectionio/static/styles/scss/styles.scss index d799289b..90b0ffd4 100644 --- a/changedetectionio/static/styles/scss/styles.scss +++ b/changedetectionio/static/styles/scss/styles.scss @@ -54,8 +54,47 @@ a.github-link { } } -button.toggle-theme { - width: 4rem; +#toggle-light-mode { + width: 3rem; + .icon-dark { + display: none; + } + + &.dark { + .icon-light { + display: none; + } + + .icon-dark { + display: block; + } + } +} + +#toggle-search { + width: 2rem; +} + +#search-q { + opacity: 0; + -webkit-transition: all .9s ease; + -moz-transition: all .9s ease; + transition: all .9s ease; + width: 0; + display: none; + &.expanded { + width: auto; + display: inline-block; + + opacity: 1; + } +} +#search-result-info { + color: #fff; +} + +button.toggle-button { + vertical-align: middle; background: transparent; border: none; cursor: pointer; @@ -74,19 +113,7 @@ button.toggle-theme { display: block; } - .icon-dark { - display: none; - } - &.dark { - .icon-light { - display: none; - } - - .icon-dark { - display: block; - } - } } .pure-menu-horizontal { diff --git a/changedetectionio/static/styles/styles.css b/changedetectionio/static/styles/styles.css index 9f9fc55a..e6d866e0 100644 --- a/changedetectionio/static/styles/styles.css +++ b/changedetectionio/static/styles/styles.css @@ -331,23 +331,44 @@ a.github-link { a.github-link:hover { color: var(--color-icon-github-hover); } -button.toggle-theme { - width: 4rem; +#toggle-light-mode { + width: 3rem; } + #toggle-light-mode .icon-dark { + display: none; } + #toggle-light-mode.dark .icon-light { + display: none; } + #toggle-light-mode.dark .icon-dark { + display: block; } + +#toggle-search { + width: 2rem; } + +#search-q { + opacity: 0; + -webkit-transition: all .9s ease; + -moz-transition: all .9s ease; + transition: all .9s ease; + width: 0; + display: none; } + #search-q.expanded { + width: auto; + display: inline-block; + opacity: 1; } + +#search-result-info { + color: #fff; } + +button.toggle-button { + vertical-align: middle; background: transparent; border: none; cursor: pointer; color: var(--color-icon-github); } - button.toggle-theme:hover { + button.toggle-button:hover { color: var(--color-icon-github-hover); } - button.toggle-theme svg { + button.toggle-button svg { fill: currentColor; } - button.toggle-theme .icon-light { - display: block; } - button.toggle-theme .icon-dark { - display: none; } - button.toggle-theme.dark .icon-light { - display: none; } - button.toggle-theme.dark .icon-dark { + button.toggle-button .icon-light { display: block; } .pure-menu-horizontal { diff --git a/changedetectionio/store.py b/changedetectionio/store.py index 123e5db7..f69eb907 100644 --- a/changedetectionio/store.py +++ b/changedetectionio/store.py @@ -366,19 +366,21 @@ class ChangeDetectionStore: def save_error_text(self, watch_uuid, contents): if not self.data['watching'].get(watch_uuid): return - target_path = os.path.join(self.datastore_path, watch_uuid, "last-error.txt") + self.data['watching'][watch_uuid].ensure_data_dir_exists() + target_path = os.path.join(self.datastore_path, watch_uuid, "last-error.txt") with open(target_path, 'w') as f: f.write(contents) def save_xpath_data(self, watch_uuid, data, as_error=False): + if not self.data['watching'].get(watch_uuid): return if as_error: target_path = os.path.join(self.datastore_path, watch_uuid, "elements-error.json") else: target_path = os.path.join(self.datastore_path, watch_uuid, "elements.json") - + self.data['watching'][watch_uuid].ensure_data_dir_exists() with open(target_path, 'w') as f: f.write(json.dumps(data)) f.close() diff --git a/changedetectionio/templates/_common_fields.jinja b/changedetectionio/templates/_common_fields.jinja index 0cef1f8f..c8ffdb00 100644 --- a/changedetectionio/templates/_common_fields.jinja +++ b/changedetectionio/templates/_common_fields.jinja @@ -115,7 +115,7 @@ URLs generated by changedetection.io (such as {{ '{{diff_url}}' }}) require the BASE_URL environment variable set.
Your BASE_URL var is currently "{{settings_application['current_base_url']}}"
- Warning: Contents of {{ '{{diff}}' }}, {{ '{{diff_removed}}' }}, and {{ '{{diff_added}}' }} depend on how the difference algorithm perceives the change. For example, an addition or removal could be perceived as a change in some cases. More Here
+ Warning: Contents of {{ '{{diff}}' }}, {{ '{{diff_removed}}' }}, and {{ '{{diff_added}}' }} depend on how the difference algorithm perceives the change. For example, an addition or removal could be perceived as a change in some cases. More Here
diff --git a/changedetectionio/templates/base.html b/changedetectionio/templates/base.html index 0efda3db..30ea733d 100644 --- a/changedetectionio/templates/base.html +++ b/changedetectionio/templates/base.html @@ -82,11 +82,21 @@ LOG OUT {% endif %} +
  • + +
    + + + +
    +
  • {% if dark_mode %} {% set darkClass = 'dark' %} {% endif %} -