From 0f8e164e8e1f3a6ca9a8c119822d5cadb106326d Mon Sep 17 00:00:00 2001 From: David Angulo Date: Thu, 25 Mar 2021 19:38:56 -0600 Subject: [PATCH 01/46] feat: Add 'Automatic' option for desk theme --- frappe/core/doctype/user/user.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json index 747ace5de6..10e9e63d0e 100644 --- a/frappe/core/doctype/user/user.json +++ b/frappe/core/doctype/user/user.json @@ -594,7 +594,7 @@ "fieldname": "desk_theme", "fieldtype": "Select", "label": "Desk Theme", - "options": "Light\nDark" + "options": "Light\nDark\nAutomatic" }, { "fieldname": "module_profile", From bfce0ca52f4d6695955c4ae950b2ab1d50fde5c1 Mon Sep 17 00:00:00 2001 From: David Angulo Date: Thu, 25 Mar 2021 19:39:15 -0600 Subject: [PATCH 02/46] feat: Add desk_theme to bootinfo --- frappe/sessions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frappe/sessions.py b/frappe/sessions.py index 3babf1db12..bb54418a17 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -159,6 +159,8 @@ def get(): bootinfo["setup_complete"] = cint(frappe.db.get_single_value('System Settings', 'setup_complete')) bootinfo["is_first_startup"] = cint(frappe.db.get_single_value('System Settings', 'is_first_startup')) + bootinfo['desk_theme'] = frappe.db.get_value("User", frappe.session.user, "desk_theme") or 'Light' + return bootinfo def get_csrf_token(): From 72126a8645e0112c4ce5925d4e54efcc534483fe Mon Sep 17 00:00:00 2001 From: David Angulo Date: Thu, 25 Mar 2021 19:41:19 -0600 Subject: [PATCH 03/46] feat: Change default desk theme behaviour --- frappe/www/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/www/app.py b/frappe/www/app.py index 6088c413dc..656ebbe45c 100644 --- a/frappe/www/app.py +++ b/frappe/www/app.py @@ -46,7 +46,7 @@ def get_context(context): "include_css": hooks["app_include_css"], "sounds": hooks["sounds"], "boot": boot if context.get("for_mobile") else boot_json, - "desk_theme": desk_theme or "Light", + "desk_theme": desk_theme if not desk_theme == 'Automatic' else 'Light', "csrf_token": csrf_token, "google_analytics_id": frappe.conf.get("google_analytics_id"), "google_analytics_anonymize_ip": frappe.conf.get("google_analytics_anonymize_ip"), From 1100180576a3560774f6b7f210479e87ae43297d Mon Sep 17 00:00:00 2001 From: David Angulo Date: Thu, 25 Mar 2021 19:43:51 -0600 Subject: [PATCH 04/46] feat: Add listener to system theme change, to update desk theme accordingly --- frappe/public/js/frappe/desk.js | 6 +++++ frappe/public/js/frappe/ui/theme_switcher.js | 26 +++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 250d308b7e..8094c0261b 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -63,6 +63,12 @@ frappe.Application = Class.extend({ } }); + if(frappe.boot.desk_theme == 'Automatic') { + frappe.ui.add_system_theme_switch_listener(); + const startup_theme = frappe.ui.dark_theme_media_query.matches ? 'dark' : 'light'; + frappe.ui.toggle_theme(startup_theme); + } + this.set_rtl(); // page container diff --git a/frappe/public/js/frappe/ui/theme_switcher.js b/frappe/public/js/frappe/ui/theme_switcher.js index 317198bca5..d78dd6455c 100644 --- a/frappe/public/js/frappe/ui/theme_switcher.js +++ b/frappe/public/js/frappe/ui/theme_switcher.js @@ -82,11 +82,15 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { return preview; } - toggle_theme(theme) { + toggle_theme(theme, save_preferences=true) { this.current_theme = theme.toLowerCase(); document.documentElement.setAttribute("data-theme", this.current_theme); frappe.show_alert("Theme Changed", 3); + if(!save_preferences) { + return; + } + frappe.xcall("frappe.core.doctype.user.user.switch_theme", { theme: toTitle(theme) }); @@ -99,3 +103,23 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { this.dialog.hide(); } }; + +frappe.ui.add_system_theme_switch_listener = function() { + const toggle_theme = frappe.ui.toggle_theme; + + frappe.ui.dark_theme_media_query.addEventListener('change', function(e) { + if (e.matches) { + toggle_theme('dark'); + return; + } + + toggle_theme('light'); + }) +} + +frappe.ui.dark_theme_media_query = window.matchMedia("(prefers-color-scheme: dark)"); + +frappe.ui.toggle_theme = function(theme) { + const theme_switcher = new frappe.ui.ThemeSwitcher(); + theme_switcher.toggle_theme(theme, false); +} \ No newline at end of file From c1fd70b997484797a6f3d464ab4ab807c08fc935 Mon Sep 17 00:00:00 2001 From: David Angulo Date: Thu, 25 Mar 2021 20:51:58 -0600 Subject: [PATCH 05/46] feat: Add options to ThemeSwitcher.toggle_theme to configure if we want to show an alert and save preferences on change --- frappe/public/js/frappe/ui/theme_switcher.js | 22 ++++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/frappe/public/js/frappe/ui/theme_switcher.js b/frappe/public/js/frappe/ui/theme_switcher.js index d78dd6455c..fb43c1fae0 100644 --- a/frappe/public/js/frappe/ui/theme_switcher.js +++ b/frappe/public/js/frappe/ui/theme_switcher.js @@ -82,18 +82,19 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { return preview; } - toggle_theme(theme, save_preferences=true) { + toggle_theme(theme, options = {save_preferences:true, show_alert:true}) { this.current_theme = theme.toLowerCase(); document.documentElement.setAttribute("data-theme", this.current_theme); - frappe.show_alert("Theme Changed", 3); - if(!save_preferences) { - return; + if (options && options.show_alert) { + frappe.show_alert("Theme Changed", 3); + } + + if(options && options.save_preferences) { + frappe.xcall("frappe.core.doctype.user.user.switch_theme", { + theme: toTitle(theme) + }); } - - frappe.xcall("frappe.core.doctype.user.user.switch_theme", { - theme: toTitle(theme) - }); } show() { this.dialog.show(); @@ -121,5 +122,8 @@ frappe.ui.dark_theme_media_query = window.matchMedia("(prefers-color-scheme: dar frappe.ui.toggle_theme = function(theme) { const theme_switcher = new frappe.ui.ThemeSwitcher(); - theme_switcher.toggle_theme(theme, false); + theme_switcher.toggle_theme(theme, { + save_preferences: false, + show_alert: false + }); } \ No newline at end of file From a1579db65dde95520705100176dd7ddff637e5a9 Mon Sep 17 00:00:00 2001 From: David Angulo Date: Thu, 25 Mar 2021 21:08:05 -0600 Subject: [PATCH 06/46] fix: fix sider validation --- frappe/public/js/frappe/desk.js | 2 +- frappe/public/js/frappe/ui/theme_switcher.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 8094c0261b..682f730d3c 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -63,7 +63,7 @@ frappe.Application = Class.extend({ } }); - if(frappe.boot.desk_theme == 'Automatic') { + if (frappe.boot.desk_theme == 'Automatic') { frappe.ui.add_system_theme_switch_listener(); const startup_theme = frappe.ui.dark_theme_media_query.matches ? 'dark' : 'light'; frappe.ui.toggle_theme(startup_theme); diff --git a/frappe/public/js/frappe/ui/theme_switcher.js b/frappe/public/js/frappe/ui/theme_switcher.js index fb43c1fae0..56263824dd 100644 --- a/frappe/public/js/frappe/ui/theme_switcher.js +++ b/frappe/public/js/frappe/ui/theme_switcher.js @@ -82,7 +82,7 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { return preview; } - toggle_theme(theme, options = {save_preferences:true, show_alert:true}) { + toggle_theme(theme, options = { save_preferences:true, show_alert:true }) { this.current_theme = theme.toLowerCase(); document.documentElement.setAttribute("data-theme", this.current_theme); @@ -90,7 +90,7 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { frappe.show_alert("Theme Changed", 3); } - if(options && options.save_preferences) { + if (options && options.save_preferences) { frappe.xcall("frappe.core.doctype.user.user.switch_theme", { theme: toTitle(theme) }); @@ -115,8 +115,8 @@ frappe.ui.add_system_theme_switch_listener = function() { } toggle_theme('light'); - }) -} + }); +}; frappe.ui.dark_theme_media_query = window.matchMedia("(prefers-color-scheme: dark)"); @@ -126,4 +126,4 @@ frappe.ui.toggle_theme = function(theme) { save_preferences: false, show_alert: false }); -} \ No newline at end of file +}; \ No newline at end of file From 2f32c4f19698c1031fa2fa83dcd3fd8b19051b4f Mon Sep 17 00:00:00 2001 From: David Angulo Date: Fri, 26 Mar 2021 10:01:18 -0600 Subject: [PATCH 07/46] fix: fix sider validation --- frappe/public/js/frappe/ui/theme_switcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/theme_switcher.js b/frappe/public/js/frappe/ui/theme_switcher.js index 56263824dd..fbf6575bc4 100644 --- a/frappe/public/js/frappe/ui/theme_switcher.js +++ b/frappe/public/js/frappe/ui/theme_switcher.js @@ -82,7 +82,7 @@ frappe.ui.ThemeSwitcher = class ThemeSwitcher { return preview; } - toggle_theme(theme, options = { save_preferences:true, show_alert:true }) { + toggle_theme(theme, options = { save_preferences: true, show_alert: true }) { this.current_theme = theme.toLowerCase(); document.documentElement.setAttribute("data-theme", this.current_theme); From e00eb958367fc7567cf1a51f0370e64a57b8f95c Mon Sep 17 00:00:00 2001 From: David Angulo Date: Tue, 6 Apr 2021 10:35:56 -0500 Subject: [PATCH 08/46] fix: Update modified timestamp so the update will pickup the changes --- frappe/core/doctype/user/user.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json index 10e9e63d0e..4d8d907ee6 100644 --- a/frappe/core/doctype/user/user.json +++ b/frappe/core/doctype/user/user.json @@ -669,7 +669,7 @@ } ], "max_attachments": 5, - "modified": "2021-02-01 16:11:06.037543", + "modified": "2021-04-06 16:11:06.037543", "modified_by": "Administrator", "module": "Core", "name": "User", From 632e3acc01b3ea2965af684f6c383dc07fc72363 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Thu, 28 Oct 2021 20:49:34 +0530 Subject: [PATCH 09/46] refactor: New Feedback & Comment Design for Blog Post --- frappe/core/doctype/feedback/feedback.json | 39 ++-- frappe/public/icons/timeless/symbol-defs.svg | 20 ++ frappe/public/scss/website/blog.scss | 99 +++++++++ frappe/templates/includes/avatar_macro.html | 6 +- .../templates/includes/comments/comment.html | 30 ++- .../templates/includes/comments/comments.html | 138 ++++++++----- .../templates/includes/comments/comments.py | 3 + .../templates/includes/feedback/feedback.html | 193 +++++------------- .../templates/includes/feedback/feedback.py | 47 ++--- frappe/website/doctype/blog_post/blog_post.py | 30 ++- .../blog_post/templates/blog_post.html | 16 +- .../doctype/blog_settings/blog_settings.json | 26 ++- .../doctype/blog_settings/blog_settings.py | 5 +- 13 files changed, 367 insertions(+), 285 deletions(-) diff --git a/frappe/core/doctype/feedback/feedback.json b/frappe/core/doctype/feedback/feedback.json index b77e7a6677..998278e89e 100644 --- a/frappe/core/doctype/feedback/feedback.json +++ b/frappe/core/doctype/feedback/feedback.json @@ -8,34 +8,15 @@ "reference_doctype", "reference_name", "column_break_3", - "rating", - "ip_address", - "section_break_6", - "feedback" + "like", + "dislike", + "ip_address" ], "fields": [ { "fieldname": "column_break_3", "fieldtype": "Column Break" }, - { - "fieldname": "rating", - "fieldtype": "Float", - "in_list_view": 1, - "label": "Rating", - "precision": "1", - "reqd": 1 - }, - { - "fieldname": "section_break_6", - "fieldtype": "Section Break" - }, - { - "fieldname": "feedback", - "fieldtype": "Small Text", - "label": "Feedback", - "reqd": 1 - }, { "fieldname": "reference_doctype", "fieldtype": "Select", @@ -57,11 +38,23 @@ "hidden": 1, "label": "IP Address", "read_only": 1 + }, + { + "default": "0", + "fieldname": "like", + "fieldtype": "Check", + "label": "Like" + }, + { + "default": "0", + "fieldname": "dislike", + "fieldtype": "Check", + "label": "Dislike" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-06-23 12:45:42.045696", + "modified": "2021-10-27 22:33:58.362849", "modified_by": "Administrator", "module": "Core", "name": "Feedback", diff --git a/frappe/public/icons/timeless/symbol-defs.svg b/frappe/public/icons/timeless/symbol-defs.svg index b878f713e9..593303e790 100644 --- a/frappe/public/icons/timeless/symbol-defs.svg +++ b/frappe/public/icons/timeless/symbol-defs.svg @@ -712,4 +712,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/frappe/public/scss/website/blog.scss b/frappe/public/scss/website/blog.scss index ea82efed21..c842554514 100644 --- a/frappe/public/scss/website/blog.scss +++ b/frappe/public/scss/website/blog.scss @@ -1,3 +1,7 @@ +:root { + --comment-timeline-height: 60px; +} + .blog-list { display: flex; flex-wrap: wrap; @@ -96,4 +100,99 @@ margin-top: 3rem; } } + + + .feedback-button svg, .comment-count svg { + vertical-align: sub; + } + + .blog-feedback { + .feedback-header { + display: flex; + justify-content: space-between; + + .like-dislike { + display: flex; + + .like-icon, .dislike-icon { + cursor: pointer; + } + } + } + } + + .blog-comments { + .add-comment-section { + .login-required { + padding: var(--padding-sm); + border-radius: var(--border-radius-sm); + box-shadow: var(--card-shadow); + } + + .new-comment { + display: flex; + padding: var(--padding-lg); + box-shadow: var(--card-shadow); + border-radius: var(--border-radius-md); + + .new-comment-fields { + flex: 1; + + .form-label { + font-weight: var(--text-bold); + } + + .comment-text-area textarea { + resize: none; + } + + @media (min-width: 576px) { + .comment-by { + padding-right: 0px !important; + padding-bottom: 0px !important; + } + } + } + } + } + + + #comment-list { + position: relative; + padding-left: var(--padding-xl); + padding-top: var(--padding-lg); + + &::before { + content: " "; + top: 0; + position: absolute; + bottom: var(--comment-timeline-height); + border-left: 1px solid var(--dark-border-color); + } + + .comment-row { + position: relative; + + .comment-avatar { + position: absolute; + top: 10px; + left: -17px; + border-radius: var(--border-radius-full); + box-shadow: var(--shadow-xs); + } + + .comment-content { + box-shadow: var(--card-shadow); + border-radius: var(--border-radius-md); + padding: var(--padding-md); + margin-left: 35px; + flex: 1; + + .content p{ + margin-bottom: 0px; + } + } + } + } + } } diff --git a/frappe/templates/includes/avatar_macro.html b/frappe/templates/includes/avatar_macro.html index 6983477f9c..b652b573b3 100644 --- a/frappe/templates/includes/avatar_macro.html +++ b/frappe/templates/includes/avatar_macro.html @@ -1,6 +1,6 @@ -{% macro avatar(user_id=None, css_style=None) %} +{% macro avatar(user_id=None, css_style=None, size="avatar-small") %} {% set user_info = frappe.utils.get_user_info_for_avatar(user_id) %} - + {% if user_info.image %} - {{ frappe.utils.get_abbr(user_info.name) }} + {{ frappe.utils.get_abbr(user_info.name).upper() }} {% endif %} diff --git a/frappe/templates/includes/comments/comment.html b/frappe/templates/includes/comments/comment.html index 08a2b79ee6..3ce5224db2 100644 --- a/frappe/templates/includes/comments/comment.html +++ b/frappe/templates/includes/comments/comment.html @@ -1,18 +1,14 @@ -{% from "frappe/templates/includes/macros.html" import square_image_with_fallback %} +{% from "frappe/templates/includes/avatar_macro.html" import avatar %} -
- {{ square_image_with_fallback(src=frappe.get_gravatar(comment.comment_email or comment.sender), size='extra-small', alt=comment.sender_full_name, class='align-self-start mr-4') }} -
-
- - {{ comment.sender_full_name or comment.comment_by }} - - - {{ comment.creation | global_date_format }} - -
-
- {{ comment.content | markdown }} -
-
-
+
+
+ {{ avatar(user_id=(comment.comment_email or comment.sender), size='avatar-medium') }} +
+
+
+ {{ comment.sender_full_name or comment.comment_by }} + {{ frappe.utils.pretty_date(comment.creation) }} +
+
{{ comment.content | markdown }}
+
+
\ No newline at end of file diff --git a/frappe/templates/includes/comments/comments.html b/frappe/templates/includes/comments/comments.html index 935fa5367e..c0bb33fd38 100644 --- a/frappe/templates/includes/comments/comments.html +++ b/frappe/templates/includes/comments/comments.html @@ -1,55 +1,82 @@
- {% if comment_text %} -
{{ comment_text }}
- {% endif %} {% if not comment_list %} -
-

{{ _("No comments yet. Start a new discussion.") }}

-
+
+

{{ _("No comments yet. Start a new discussion.") }}

+
+ {% endif %} + + {% if not is_communication %} +
+ +
+
+
+
+ +
+
Add a comment
+ +
Ctrl+Enter to add comment
+
+ +
+
+
+
+
{% endif %}
{% for comment in comment_list %} -
{% include "templates/includes/comments/comment.html" %} -
{% endfor %}
-{% if not is_communication %} -
- - -
- {{ _("Add Comment") }} - -
-
-{% endif %} diff --git a/frappe/templates/includes/comments/comments.py b/frappe/templates/includes/comments/comments.py index 3bba388ac2..e352c7368b 100644 --- a/frappe/templates/includes/comments/comments.py +++ b/frappe/templates/includes/comments/comments.py @@ -3,11 +3,14 @@ import frappe import re from frappe.website.utils import clear_cache +from frappe.rate_limiter import rate_limit from frappe.utils import add_to_date, now +from frappe.website.doctype.blog_settings.blog_settings import get_comment_limit from frappe import _ @frappe.whitelist(allow_guest=True) +@rate_limit(key='reference_name', limit=get_comment_limit, seconds=60*60) def add_comment(comment, comment_email, comment_by, reference_doctype, reference_name, route): doc = frappe.get_doc(reference_doctype, reference_name) diff --git a/frappe/templates/includes/feedback/feedback.html b/frappe/templates/includes/feedback/feedback.html index f180fa5e42..fd509f9db3 100644 --- a/frappe/templates/includes/feedback/feedback.html +++ b/frappe/templates/includes/feedback/feedback.html @@ -1,160 +1,77 @@ -
- {% endif %} - {% if not disable_feedback %} -
- {% include 'templates/includes/feedback/feedback.html' %} -
- {% endif %}