diff --git a/web_dark_mode/README.rst b/web_dark_mode/README.rst new file mode 100644 index 000000000000..ca3d45e9e65c --- /dev/null +++ b/web_dark_mode/README.rst @@ -0,0 +1,82 @@ +========= +Dark Mode +========= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:92c42b374159b10469f7a113505b270486a72f4a3bec1552c591c18146e82035 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/18.0/web_dark_mode + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-18-0/web-18-0-web_dark_mode + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/web&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This modules offers the dark mode for Odoo CE. The dark mode can be +activated by every user in the user menu in the top right. + +**Table of contents** + +.. contents:: + :local: + +Known issues / Roadmap +====================== + +- Implement dark mode for PoS with a glue module + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* initOS GmbH + +Contributors +------------ + +- Florian Kantelberg + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_dark_mode/__init__.py b/web_dark_mode/__init__.py new file mode 100644 index 000000000000..1d408a8a039e --- /dev/null +++ b/web_dark_mode/__init__.py @@ -0,0 +1,4 @@ +# © 2022 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models diff --git a/web_dark_mode/__manifest__.py b/web_dark_mode/__manifest__.py new file mode 100644 index 000000000000..20bfe07c93b3 --- /dev/null +++ b/web_dark_mode/__manifest__.py @@ -0,0 +1,25 @@ +# © 2022 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Dark Mode", + "summary": "Enabled Dark Mode for the Odoo Backend", + "license": "AGPL-3", + "version": "18.0.1.0.0", + "website": "https://github.com/OCA/web", + "author": "initOS GmbH, Odoo Community Association (OCA)", + "depends": ["web"], + "excludes": ["web_enterprise"], + "installable": True, + "assets": { + "web.assets_web_dark": [ + ("prepend", "web_dark_mode/static/src/scss/variables.scss"), + ], + "web.assets_backend": [ + "web_dark_mode/static/src/js/switch_item.esm.js", + ], + }, + "data": [ + "views/res_users_views.xml", + ], +} diff --git a/web_dark_mode/i18n/es.po b/web_dark_mode/i18n/es.po new file mode 100644 index 000000000000..903638c864d5 --- /dev/null +++ b/web_dark_mode/i18n/es.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-09-02 20:35+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "Modo Oscuro" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "Modo Oscuro en Función del Dispositivo" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "Enrutamiento HTTP" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "Usuario" diff --git a/web_dark_mode/i18n/es_AR.po b/web_dark_mode/i18n/es_AR.po new file mode 100644 index 000000000000..1ad2d1f79e73 --- /dev/null +++ b/web_dark_mode/i18n/es_AR.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-01-01 21:45+0000\n" +"Last-Translator: Ignacio Buioli \n" +"Language-Team: none\n" +"Language: es_AR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "Modo Oscuro" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "Dispositivo que Depende del Modo Oscuro" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "Ruteo HTTP" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "Usuario" diff --git a/web_dark_mode/i18n/fr.po b/web_dark_mode/i18n/fr.po new file mode 100644 index 000000000000..3333b16a9660 --- /dev/null +++ b/web_dark_mode/i18n/fr.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-10-23 18:56+0000\n" +"Last-Translator: Grégory Moka Tourisme \n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "Mode sombre" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "Utilisateur" diff --git a/web_dark_mode/i18n/hr.po b/web_dark_mode/i18n/hr.po new file mode 100644 index 000000000000..21e8842000f7 --- /dev/null +++ b/web_dark_mode/i18n/hr.po @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-02-16 14:23+0000\n" +"Last-Translator: Bole \n" +"Language-Team: none\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "Tamni način" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "Tamni način zavisi od uređaja" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "HTTP Routing" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "Korisnik" diff --git a/web_dark_mode/i18n/it.po b/web_dark_mode/i18n/it.po new file mode 100644 index 000000000000..e14a675b293c --- /dev/null +++ b/web_dark_mode/i18n/it.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-11-27 11:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "Dark mode" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "Dark mode dipendente dal dispositivo" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "Instradamento HTTP" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "Utente" diff --git a/web_dark_mode/i18n/tr.po b/web_dark_mode/i18n/tr.po new file mode 100644 index 000000000000..0cd019cf46af --- /dev/null +++ b/web_dark_mode/i18n/tr.po @@ -0,0 +1,40 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-03-06 20:08+0000\n" +"Last-Translator: Ediz Duman \n" +"Language-Team: none\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "Koyu Mod" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "Cihaza Bağlı Karanlık Mod" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "HTTP Yönlendirme" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "Kullanıcı" diff --git a/web_dark_mode/i18n/web_dark_mode.pot b/web_dark_mode/i18n/web_dark_mode.pot new file mode 100644 index 000000000000..f3daced67eea --- /dev/null +++ b/web_dark_mode/i18n/web_dark_mode.pot @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "" diff --git a/web_dark_mode/i18n/zh.po b/web_dark_mode/i18n/zh.po new file mode 100644 index 000000000000..ad8461437429 --- /dev/null +++ b/web_dark_mode/i18n/zh.po @@ -0,0 +1,38 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_dark_mode +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: zh\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. module: web_dark_mode +#. odoo-javascript +#: code:addons/web_dark_mode/static/src/js/switch_item.esm.js:0 +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode +#, python-format +msgid "Dark Mode" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model.fields,field_description:web_dark_mode.field_res_users__dark_mode_device_dependent +msgid "Device Dependent Dark Mode" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_ir_http +msgid "HTTP Routing" +msgstr "" + +#. module: web_dark_mode +#: model:ir.model,name:web_dark_mode.model_res_users +msgid "User" +msgstr "" diff --git a/web_dark_mode/models/__init__.py b/web_dark_mode/models/__init__.py new file mode 100644 index 000000000000..d565f59dcc8d --- /dev/null +++ b/web_dark_mode/models/__init__.py @@ -0,0 +1,4 @@ +# © 2022 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import ir_http, res_users diff --git a/web_dark_mode/models/ir_http.py b/web_dark_mode/models/ir_http.py new file mode 100644 index 000000000000..e2c90b53773f --- /dev/null +++ b/web_dark_mode/models/ir_http.py @@ -0,0 +1,23 @@ +# © 2022 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models +from odoo.http import request + + +class IrHttp(models.AbstractModel): + _inherit = "ir.http" + + @classmethod + def _set_color_scheme(cls, response): + scheme = request.httprequest.cookies.get("color_scheme") + user = request.env.user + user_scheme = "dark" if getattr(user, "dark_mode", None) else "light" + device_dependent = getattr(user, "dark_mode_device_dependent", None) + if (not device_dependent) and scheme != user_scheme: + response.set_cookie("color_scheme", user_scheme) + + @classmethod + def _post_dispatch(cls, response): + cls._set_color_scheme(response) + return super()._post_dispatch(response) diff --git a/web_dark_mode/models/res_users.py b/web_dark_mode/models/res_users.py new file mode 100644 index 000000000000..be6fd3ebc05a --- /dev/null +++ b/web_dark_mode/models/res_users.py @@ -0,0 +1,26 @@ +# © 2022 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + dark_mode = fields.Boolean() + dark_mode_device_dependent = fields.Boolean("Device Dependent Dark Mode") + + @property + def SELF_READABLE_FIELDS(self): + return super().SELF_READABLE_FIELDS + [ + "dark_mode_device_dependent", + "dark_mode", + ] + + @property + def SELF_WRITEABLE_FIELDS(self): + return super().SELF_WRITEABLE_FIELDS + [ + "dark_mode_device_dependent", + "dark_mode", + ] diff --git a/web_dark_mode/pyproject.toml b/web_dark_mode/pyproject.toml new file mode 100644 index 000000000000..4231d0cccb3d --- /dev/null +++ b/web_dark_mode/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/web_dark_mode/readme/CONTRIBUTORS.md b/web_dark_mode/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..5710e10104ac --- /dev/null +++ b/web_dark_mode/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Florian Kantelberg \ diff --git a/web_dark_mode/readme/DESCRIPTION.md b/web_dark_mode/readme/DESCRIPTION.md new file mode 100644 index 000000000000..7d90c04edb1d --- /dev/null +++ b/web_dark_mode/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This modules offers the dark mode for Odoo CE. The dark mode can be +activated by every user in the user menu in the top right. diff --git a/web_dark_mode/readme/ROADMAP.md b/web_dark_mode/readme/ROADMAP.md new file mode 100644 index 000000000000..b1437e5f398e --- /dev/null +++ b/web_dark_mode/readme/ROADMAP.md @@ -0,0 +1 @@ +- Implement dark mode for PoS with a glue module diff --git a/web_dark_mode/static/description/icon.png b/web_dark_mode/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/web_dark_mode/static/description/icon.png differ diff --git a/web_dark_mode/static/description/index.html b/web_dark_mode/static/description/index.html new file mode 100644 index 000000000000..f47fc8649abe --- /dev/null +++ b/web_dark_mode/static/description/index.html @@ -0,0 +1,431 @@ + + + + + +Codestin Search App + + + +
+

Dark Mode

+ + +

Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runboat

+

This modules offers the dark mode for Odoo CE. The dark mode can be +activated by every user in the user menu in the top right.

+

Table of contents

+ +
+

Known issues / Roadmap

+
    +
  • Implement dark mode for PoS with a glue module
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • initOS GmbH
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/web project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/web_dark_mode/static/src/js/switch_item.esm.js b/web_dark_mode/static/src/js/switch_item.esm.js new file mode 100644 index 000000000000..63530ae974e9 --- /dev/null +++ b/web_dark_mode/static/src/js/switch_item.esm.js @@ -0,0 +1,50 @@ +/** @odoo-module **/ + +import {_t} from "@web/core/l10n/translation"; +import {browser} from "@web/core/browser/browser"; +import {cookie} from "@web/core/browser/cookie"; +import {registry} from "@web/core/registry"; +import {user} from "@web/core/user"; + +export function darkModeSwitchItem(env) { + return { + type: "switch", + id: "color_scheme.switch", + description: _t("Dark Mode"), + callback: () => { + env.services.color_scheme.switchColorScheme(); + }, + isChecked: cookie.get("color_scheme") === "dark", + sequence: 40, + }; +} + +export const colorSchemeService = { + dependencies: ["orm", "ui"], + + async start(env, {orm, ui}) { + registry.category("user_menuitems").add("darkmode", darkModeSwitchItem); + + if (!cookie.get("color_scheme")) { + const match_media = window.matchMedia("(prefers-color-scheme: dark)"); + const dark_mode = match_media.matches; + cookie.set("color_scheme", dark_mode ? "dark" : "light"); + if (dark_mode) browser.location.reload(); + } + + return { + async switchColorScheme() { + const scheme = cookie.get("color_scheme") === "dark" ? "light" : "dark"; + cookie.set("color_scheme", scheme); + await orm.write("res.users", [user.userId], { + dark_mode: scheme === "dark", + }); + + ui.block(); + browser.location.reload(); + }, + }; + }, +}; + +registry.category("services").add("color_scheme", colorSchemeService); diff --git a/web_dark_mode/static/src/scss/variables.scss b/web_dark_mode/static/src/scss/variables.scss new file mode 100644 index 000000000000..a32c59d44373 --- /dev/null +++ b/web_dark_mode/static/src/scss/variables.scss @@ -0,0 +1,65 @@ +$o-webclient-color-scheme: dark; + +$o-white: #000000; +$o-black: #ffffff; + +$o-gray-100: #191c24; +$o-gray-200: #242733; +$o-gray-300: #3f4149; +$o-gray-400: #5f6167; +$o-gray-500: #797a80; +$o-gray-600: #94959a; +$o-gray-700: #b0b0b4; +$o-gray-800: #cccccf; +$o-gray-900: #e9e9eb; + +$o-community-color: $o-gray-400; +$o-enterprise-color: $o-gray-400; +$o-enterprise-primary-color: $o-gray-500; +$o-brand-primary: $o-gray-600; +$o-brand-secondary: $o-gray-700; + +$o-success: #28a745; +$o-info: #74dcf3; +$o-warning: #ff7b00; +$o-danger: #ff0020; + +$primary: $o-gray-800; + +$o-main-bg-color: #f0eeee; +$o-main-favorite-color: #f3cc00; +$o-main-code-color: #d2317b; + +$o-view-background-color: $o-white; +$o-view-background-color: $o-gray-100; +$o-shadow-color: #c0c0c0; + +$o-form-lightsecondary: #ccc; + +$o-list-footer-bg-color: #eee; + +$o-tooltip-arrow-color: white; + +// Layout +$o-dropdown-box-shadow: 0 1rem 1.1rem rgba(#fff, 0.1); + +// == List group + +$o-list-group-active-bg: lighten(saturate(adjust-hue($o-info, 15), 1.8), 5); +$o-list-footer-bg-color: $o-gray-200; + +// == Badges + +// Define a minimum width. This value is arbitrary and strictly font-related. +$o-datepicker-week-color: #8f8f8f; + +$component-active-bg: red; + +$o-webclient-background-color: $o-gray-300; + +.o-settings-form-view .o_base_settings { + --settings__tab-bg: #{$o-gray-100}; + --settings__tab-bg--active: #{$o-gray-300}; + --settings__tab-color: #{$o-gray-700}; + --settings__title-bg: #{$o-gray-100}; +} diff --git a/web_dark_mode/tests/__init__.py b/web_dark_mode/tests/__init__.py new file mode 100644 index 000000000000..634cfc9d3dc0 --- /dev/null +++ b/web_dark_mode/tests/__init__.py @@ -0,0 +1,4 @@ +# © 2022 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_dark_mode diff --git a/web_dark_mode/tests/test_dark_mode.py b/web_dark_mode/tests/test_dark_mode.py new file mode 100644 index 000000000000..466ee7e3ac19 --- /dev/null +++ b/web_dark_mode/tests/test_dark_mode.py @@ -0,0 +1,35 @@ +# © 2022 Florian Kantelberg - initOS GmbH +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from unittest.mock import MagicMock + +import odoo.http +from odoo.tests import common + + +class TestDarkMode(common.TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.request = MagicMock(env=cls.env) + odoo.http._request_stack.push(cls.request) + + def test_dark_mode_cookie(self): + response = MagicMock() + + # Cookie is set because the color_scheme changed + self.request.httprequest.cookies = {"color_scheme": "dark"} + self.env["ir.http"]._post_dispatch(response) + response.set_cookie.assert_called_with("color_scheme", "light") + + # Cookie isn't set because the color_scheme is the same + response.reset_mock() + self.request.httprequest.cookies = {"color_scheme": "light"} + self.env["ir.http"]._post_dispatch(response) + response.set_cookie.assert_not_called() + + # Cookie isn't set because it's device dependent + self.env.user.dark_mode_device_dependent = True + self.request.httprequest.cookies = {"color_scheme": "dark"} + self.env["ir.http"]._post_dispatch(response) + response.set_cookie.assert_not_called() diff --git a/web_dark_mode/views/res_users_views.xml b/web_dark_mode/views/res_users_views.xml new file mode 100644 index 000000000000..47f02427f757 --- /dev/null +++ b/web_dark_mode/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users + + + + + + + + + +