diff --git a/daemon.py b/daemon.py index 9007ed3b6..152285641 100644 --- a/daemon.py +++ b/daemon.py @@ -179,6 +179,8 @@ from cache import getPersonFromCache from httpsig import verifyPostHeaders from theme import setTheme from theme import getTheme +from theme import enableGrayscale +from theme import disableGrayscale from schedule import runPostSchedule from schedule import runPostScheduleWatchdog from schedule import removeScheduledPosts @@ -6494,6 +6496,14 @@ class PubServer(BaseHTTPRequestHandler): if actorJson['type'] != 'Person': actorJson['type'] = 'Person' actorChanged = True + grayscale = False + if fields.get('grayscale'): + if fields['grayscale'] == 'on': + grayscale = True + if grayscale: + enableGrayscale(self.server.baseDir) + else: + disableGrayscale(self.server.baseDir) # save filtered words list filterFilename = \ self.server.baseDir + '/accounts/' + \ diff --git a/epicyon-calendar.css b/epicyon-calendar.css index 4a1148133..f31f86188 100644 --- a/epicyon-calendar.css +++ b/epicyon-calendar.css @@ -1,4 +1,5 @@ :root { + --grayscale: 0%; --main-bg-color: #282c37; --calendar-bg-color: #eee; --lines-color: black; @@ -38,6 +39,7 @@ body { font-family: 'Montserrat'; font-weight: 700; min-height: 100vh; + filter: grayscale(--grayscale); } main { @@ -180,10 +182,12 @@ tr:nth-child(even) > .calendar__day__cell:nth-child(even) { } .calendardayicon { + filter: grayscale(--grayscale); width: 100% } .buttonprev { + filter: grayscale(--grayscale); float: left; width: 10%; -ms-transform: translateY(30%); @@ -191,6 +195,7 @@ tr:nth-child(even) > .calendar__day__cell:nth-child(even) { } .buttonnext { + filter: grayscale(--grayscale); float: right; width: 10%; -ms-transform: translateY(30%) scaleX(-1); diff --git a/epicyon-follow.css b/epicyon-follow.css index 6981ea92a..3df55b7c1 100644 --- a/epicyon-follow.css +++ b/epicyon-follow.css @@ -1,6 +1,7 @@ @charset "UTF-8"; :root { + --grayscale: 0%; --main-bg-color: #282c37; --link-bg-color: #282c37; --main-fg-color: #dddddd; @@ -49,6 +50,7 @@ body, html { max-width: 100%; min-width: 600px; margin: 5% auto; + filter: grayscale(--grayscale); } a, u { @@ -89,6 +91,7 @@ a:link { } .followAvatar img { + filter: grayscale(--grayscale); border-radius: 10%; width: 20%; min-width: 200px; @@ -168,6 +171,7 @@ input[type=text] { } .options img { + filter: grayscale(--grayscale); width: 15%; } diff --git a/epicyon-login.css b/epicyon-login.css index c0279dc8b..2b3737010 100644 --- a/epicyon-login.css +++ b/epicyon-login.css @@ -1,6 +1,7 @@ @charset "UTF-8"; :root { + --grayscale: 0%; --main-bg-color: #282c37; --link-bg-color: #282c37; --main-fg-color: #dddddd; @@ -40,6 +41,7 @@ body, html { min-width: 600px; margin: 0 auto; font-size: var(--font-size); + filter: grayscale(--grayscale); } a, u { @@ -96,11 +98,13 @@ button:hover { } .imgcontainer { + filter: grayscale(--grayscale); text-align: center; margin: 24px 0 12px 0; } img.avatar { + filter: grayscale(--grayscale); width: 40%; border-radius: 50%; } diff --git a/epicyon-profile.css b/epicyon-profile.css index 247b8449e..0755aa0b7 100644 --- a/epicyon-profile.css +++ b/epicyon-profile.css @@ -1,6 +1,7 @@ @charset "UTF-8"; :root { + --grayscale: 0%; --main-bg-color: #282c37; --link-bg-color: #282c37; --dropdown-fg-color: #dddddd; @@ -70,6 +71,7 @@ body, html { min-width: 950px; margin: 0 auto; font-size: var(--font-size); + filter: grayscale(--grayscale); } a, u { @@ -107,6 +109,7 @@ a:link { } .rssfeed img { + filter: grayscale(--grayscale); width: 5%; float: right; } @@ -144,6 +147,7 @@ a:link { } .hero-image img { + filter: grayscale(--grayscale); width: 50%; } @@ -175,6 +179,7 @@ a:link { } .hero-text img.emoji { + filter: grayscale(--grayscale); width: 50px; padding: 0 0; margin: 0 0; @@ -306,6 +311,7 @@ a:link { } .container img.emoji { + filter: grayscale(--grayscale); float: none; width: 50px; margin-left: 0px; @@ -316,6 +322,7 @@ a:link { } .hero-text img.emojiprofile { + filter: grayscale(--grayscale); float: none; width: 50px; margin-left: 0px; @@ -349,6 +356,7 @@ a:link { } .container img.announceOrReply { + filter: grayscale(--grayscale); float: none; width: 30px; margin: 0 0; @@ -358,6 +366,7 @@ a:link { } .container img.DMicon { + filter: grayscale(--grayscale); float: none; width: 40px; margin: 0 0; @@ -380,12 +389,14 @@ a:link { } .container img.attachment { + filter: grayscale(--grayscale); max-width: 120%; margin-left: 5%; width: 120%; padding-bottom: 3%; } .container img.right { + filter: grayscale(--grayscale); float: var(--icons-side); margin-left: 0px; margin-right:0; @@ -393,6 +404,7 @@ a:link { margin: 0 0; } .containericons img.right { + filter: grayscale(--grayscale); float: var(--icons-side); margin-left: 20px; margin-right: 0; @@ -526,6 +538,7 @@ input[type=submit]:hover { } .dropdown img { + filter: grayscale(--grayscale); opacity: 1.0; width: 32px; height: 32px; @@ -550,6 +563,7 @@ input[type=submit]:hover { } .search-result img { + filter: grayscale(--grayscale); width: 7%; padding: 0px 30px; } @@ -574,6 +588,7 @@ input[type=submit]:hover { } .dropdown-content img { + filter: grayscale(--grayscale); width: 32px; height: 32px; padding: 0px 0px; @@ -623,6 +638,7 @@ input[type=submit]:hover { } .dropbtn img { + filter: grayscale(--grayscale); opacity: 1.0; width: 3%; height: 3%; @@ -636,6 +652,7 @@ div.gallery:hover { } div.gallery img { + filter: grayscale(--grayscale); width: 100%; height: auto; } @@ -879,6 +896,7 @@ aside .toggle-inside li { text-align: center; } .container img { + filter: grayscale(--grayscale); float: left; max-width: 400px; width: 5%; @@ -887,10 +905,12 @@ aside .toggle-inside li { border-radius: var(--image-corners); } .container img.emojisearch { + filter: grayscale(--grayscale); width: 15%; float: right; } .container img.emojicalendar { + filter: grayscale(--grayscale); float: left; max-width: 400px; width: 8%; @@ -898,6 +918,7 @@ aside .toggle-inside li { transform: translateY(-25%); } .container img.timelineicon { + filter: grayscale(--grayscale); float: var(--icons-side); margin-left: 0px; margin-right:0; @@ -906,6 +927,7 @@ aside .toggle-inside li { width: 50px; } .container img.emojiheader { + filter: grayscale(--grayscale); float: none; width: 25px; margin-left: 0px; @@ -915,6 +937,7 @@ aside .toggle-inside li { vertical-align: middle; } .containericons img { + filter: grayscale(--grayscale); float: var(--icons-side); max-width: 200px; width: 3%; @@ -922,6 +945,7 @@ aside .toggle-inside li { border-radius: 0%; } div.mediaicons img { + filter: grayscale(--grayscale); float: right; max-width: 200px; width: 6%; @@ -929,6 +953,7 @@ aside .toggle-inside li { border-radius: 0%; } div.mediaavatar img { + filter: grayscale(--grayscale); float: left; max-width: 200px; width: 5%; @@ -936,6 +961,7 @@ aside .toggle-inside li { border-radius: 0%; } .timeline-avatar img { + filter: grayscale(--grayscale); opacity: 1.0; width: 8%; height: 8%; @@ -1191,20 +1217,24 @@ aside .toggle-inside li { font-family: Arial, Helvetica, sans-serif; } .hero-text img.qrcode { + filter: grayscale(--grayscale); border-radius: 1%; width: 5%; min-width: 20px; } .hero-text img.title { + filter: grayscale(--grayscale); border-radius: 1%; width: 15%; } #msgscope label img { + filter: grayscale(--grayscale); width: 46px; height: 46px; padding: 0px 0px; } .toggle-msgScope img { + filter: grayscale(--grayscale); width: 32px; height: 32px; padding: 0px 0px; @@ -1280,6 +1310,7 @@ aside .toggle-inside li { text-align: center; } .container img { + filter: grayscale(--grayscale); float: left; max-width: 400px; width: 15%; @@ -1288,10 +1319,12 @@ aside .toggle-inside li { border-radius: var(--image-corners); } .container img.emojisearch { + filter: grayscale(--grayscale); width: 25%; float: right; } .container img.emojicalendar { + filter: grayscale(--grayscale); float: left; max-width: 400px; width: 12%; @@ -1299,6 +1332,7 @@ aside .toggle-inside li { transform: translateY(-25%); } .container img.timelineicon { + filter: grayscale(--grayscale); float: var(--icons-side); margin-left: 0px; margin-right:0; @@ -1307,6 +1341,7 @@ aside .toggle-inside li { width: 100px; } .container img.emojiheader { + filter: grayscale(--grayscale); float: none; width: 45px; margin-left: 0px; @@ -1316,6 +1351,7 @@ aside .toggle-inside li { vertical-align: middle; } div.mediaavatar img { + filter: grayscale(--grayscale); float: left; max-width: 200px; width: 8%; @@ -1323,6 +1359,7 @@ aside .toggle-inside li { border-radius: 0%; } div.mediaicons img { + filter: grayscale(--grayscale); float: right; max-width: 200px; width: 10%; @@ -1330,6 +1367,7 @@ aside .toggle-inside li { border-radius: 0%; } .containericons img { + filter: grayscale(--grayscale); float: var(--icons-side); max-width: 200px; width: 7%; @@ -1337,6 +1375,7 @@ aside .toggle-inside li { border-radius: 0%; } .timeline-avatar img { + filter: grayscale(--grayscale); opacity: 1.0; width: 15%; height: 15%; @@ -1592,20 +1631,24 @@ aside .toggle-inside li { font-family: Arial, Helvetica, sans-serif; } .hero-text img.qrcode { + filter: grayscale(--grayscale); border-radius: 1%; width: 15%; min-width: 20px; } .hero-text img.title { + filter: grayscale(--grayscale); border-radius: 1%; width: 25%; } #msgscope label img { + filter: grayscale(--grayscale); width: 64px; height: 64px; padding: 0px 0px; } .toggle-msgScope img { + filter: grayscale(--grayscale); width: 64px; height: 64px; margin: -15px 0px; diff --git a/theme.py b/theme.py index 1dc49d0fb..fea2cfdfc 100644 --- a/theme.py +++ b/theme.py @@ -87,7 +87,8 @@ def setCSSparam(css: str, param: str, value: str) -> str: def setThemeFromDict(baseDir: str, name: str, themeParams: {}) -> None: """Uses a dictionary to set a theme """ - setThemeInConfig(baseDir, name) + if name: + setThemeInConfig(baseDir, name) themeFiles = ('epicyon.css', 'login.css', 'follow.css', 'suspended.css', 'calendar.css', 'blog.css') for filename in themeFiles: @@ -144,6 +145,29 @@ def setCustomFont(baseDir: str): cssfile.write(css) +def enableGrayscale(baseDir: str): + removeTheme(baseDir) + themeParams = { + "grayscale": "100%" + } + setThemeFromDict(baseDir, None, themeParams) + grayscaleFilename = baseDir + '/accounts/.grayscale' + if not os.path.isfile(grayscaleFilename): + with open(grayscaleFilename, 'w') as grayfile: + grayfile.write(' ') + + +def disableGrayscale(baseDir: str): + removeTheme(baseDir) + themeParams = { + "grayscale": "0%" + } + setThemeFromDict(baseDir, None, themeParams) + grayscaleFilename = baseDir + '/accounts/.grayscale' + if os.path.isfile(grayscaleFilename): + os.remove(grayscaleFilename) + + def setThemeDefault(baseDir: str): removeTheme(baseDir) setThemeInConfig(baseDir, 'default') @@ -613,4 +637,9 @@ def setTheme(baseDir: str, name: str) -> bool: result = True setCustomFont(baseDir) + grayscaleFilename = baseDir + '/accounts/.grayscale' + if os.path.isfile(grayscaleFilename): + enableGrayscale(baseDir) + else: + disableGrayscale(baseDir) return result diff --git a/translations/ar.json b/translations/ar.json index 54d95f0fe..cf3cad0fb 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -250,5 +250,6 @@ "Better luck next time": "حظ أوفر في المرة القادمة", "Unavailable": "غير متوفره", "The server is busy. Please try again later": "الخادم مشغول. الرجاء معاودة المحاولة في وقت لاحق", - "Receive calendar events from this account": "تلقي أحداث التقويم من هذا الحساب" + "Receive calendar events from this account": "تلقي أحداث التقويم من هذا الحساب", + "Grayscale": "درجات الرمادي" } diff --git a/translations/ca.json b/translations/ca.json index dd8dda946..cfb4be41c 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -250,5 +250,6 @@ "Better luck next time": "Que tingueu més sort la propera vegada", "Unavailable": "No disponible", "The server is busy. Please try again later": "El servidor està ocupat. Siusplau, intenta-ho més tard", - "Receive calendar events from this account": "Rep esdeveniments del calendari des d’aquest compte" + "Receive calendar events from this account": "Rep esdeveniments del calendari des d’aquest compte", + "Grayscale": "Escala de grisos" } diff --git a/translations/cy.json b/translations/cy.json index cdf3f64ed..508955a57 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -250,5 +250,6 @@ "Better luck next time": "Gwell lwc y tro nesaf", "Unavailable": "Ddim ar gael", "The server is busy. Please try again later": "Mae'r gweinydd yn brysur. Rho gynnig Arni eto'n hwyrach", - "Receive calendar events from this account": "Derbyn digwyddiadau calendr o'r cyfrif hwn" + "Receive calendar events from this account": "Derbyn digwyddiadau calendr o'r cyfrif hwn", + "Grayscale": "Graddlwyd" } diff --git a/translations/de.json b/translations/de.json index 846c781a8..63919ff73 100644 --- a/translations/de.json +++ b/translations/de.json @@ -250,5 +250,6 @@ "Better luck next time": "Viel Glück beim nächsten Mal", "Unavailable": "Nicht verfügbar", "The server is busy. Please try again later": "Der Server ist beschäftigt. Bitte versuchen Sie es später noch einmal", - "Receive calendar events from this account": "Erhalten Sie Kalenderereignisse von diesem Konto" + "Receive calendar events from this account": "Erhalten Sie Kalenderereignisse von diesem Konto", + "Grayscale": "Graustufen" } diff --git a/translations/en.json b/translations/en.json index a8f3c2f7e..3f8e37521 100644 --- a/translations/en.json +++ b/translations/en.json @@ -250,5 +250,6 @@ "Better luck next time": "Better luck next time", "Unavailable": "Unavailable", "The server is busy. Please try again later": "The server is busy. Please try again later", - "Receive calendar events from this account": "Receive calendar events from this account" + "Receive calendar events from this account": "Receive calendar events from this account", + "Grayscale": "Grayscale" } diff --git a/translations/es.json b/translations/es.json index d3c74acef..a49c3e296 100644 --- a/translations/es.json +++ b/translations/es.json @@ -250,5 +250,6 @@ "Better luck next time": "Mejor suerte la próxima vez", "Unavailable": "Indisponible", "The server is busy. Please try again later": "El servidor esta ocupado. Por favor, inténtelo de nuevo más tarde", - "Receive calendar events from this account": "Recibe eventos de calendario de esta cuenta" + "Receive calendar events from this account": "Recibe eventos de calendario de esta cuenta", + "Grayscale": "Escala de grises" } diff --git a/translations/fr.json b/translations/fr.json index 1ce7efc35..3b59c6ce2 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -250,5 +250,6 @@ "Better luck next time": "Plus de chance la prochaine fois", "Unavailable": "Indisponible", "The server is busy. Please try again later": "Le serveur est occupé. Veuillez réessayer plus tard", - "Receive calendar events from this account": "Recevoir des événements d'agenda de ce compte" + "Receive calendar events from this account": "Recevoir des événements d'agenda de ce compte", + "Grayscale": "Niveaux de gris" } diff --git a/translations/ga.json b/translations/ga.json index d8073b3af..f905ea89e 100644 --- a/translations/ga.json +++ b/translations/ga.json @@ -250,5 +250,6 @@ "Better luck next time": "Ádh níos fearr an chéad uair eile", "Unavailable": "Níl sé ar fáil", "The server is busy. Please try again later": "Tá an freastalaí gnóthach. Bain triail eile as níos déanaí", - "Receive calendar events from this account": "Faigh imeachtaí féilire ón gcuntas seo" + "Receive calendar events from this account": "Faigh imeachtaí féilire ón gcuntas seo", + "Grayscale": "Liathscála" } diff --git a/translations/hi.json b/translations/hi.json index d28e07681..253a727a0 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -250,5 +250,6 @@ "Better luck next time": "अगली बार किस्मत तुम्हारा साथ देगी", "Unavailable": "अनुपलब्ध", "The server is busy. Please try again later": "सर्वर व्यस्त है। बाद में पुन: प्रयास करें", - "Receive calendar events from this account": "इस खाते से कैलेंडर ईवेंट प्राप्त करें" + "Receive calendar events from this account": "इस खाते से कैलेंडर ईवेंट प्राप्त करें", + "Grayscale": "ग्रेस्केल" } diff --git a/translations/it.json b/translations/it.json index 92a91a40a..a5d0ace2f 100644 --- a/translations/it.json +++ b/translations/it.json @@ -250,5 +250,6 @@ "Better luck next time": "La prossima volta sarai più fortunato", "Unavailable": "non disponibile", "The server is busy. Please try again later": "Il server è occupato. Per favore riprova più tardi", - "Receive calendar events from this account": "Ricevi eventi di calendario da questo account" + "Receive calendar events from this account": "Ricevi eventi di calendario da questo account", + "Grayscale": "Scala di grigi" } diff --git a/translations/ja.json b/translations/ja.json index d7bb800b6..33574f2c2 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -250,5 +250,6 @@ "Better luck next time": "次回は幸運を", "Unavailable": "利用できません", "The server is busy. Please try again later": "サーバーはビジーです。 後でもう一度やり直してください", - "Receive calendar events from this account": "このアカウントからカレンダーイベントを受信します" + "Receive calendar events from this account": "このアカウントからカレンダーイベントを受信します", + "Grayscale": "グレースケール" } diff --git a/translations/oc.json b/translations/oc.json index cb288851d..e1f09dfd5 100644 --- a/translations/oc.json +++ b/translations/oc.json @@ -246,5 +246,6 @@ "Better luck next time": "Better luck next time", "Unavailable": "Unavailable", "The server is busy. Please try again later": "The server is busy. Please try again later", - "Receive calendar events from this account": "Receive calendar events from this account" + "Receive calendar events from this account": "Receive calendar events from this account", + "Grayscale": "Grayscale" } diff --git a/translations/pt.json b/translations/pt.json index ccbc94ddc..fa1299000 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -250,5 +250,6 @@ "Better luck next time": "Mais sorte da próxima vez", "Unavailable": "Indisponível", "The server is busy. Please try again later": "O servidor está ocupado. Por favor, tente novamente mais tarde", - "Receive calendar events from this account": "Receba eventos da agenda desta conta" + "Receive calendar events from this account": "Receba eventos da agenda desta conta", + "Grayscale": "Escala de cinza" } diff --git a/translations/ru.json b/translations/ru.json index 616e621e2..c15f68cd4 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -250,5 +250,6 @@ "Better luck next time": "Повезет в следующий раз", "Unavailable": "Недоступен", "The server is busy. Please try again later": "Сервер занят. Пожалуйста, попробуйте позже", - "Receive calendar events from this account": "Получать события календаря от этого аккаунта" + "Receive calendar events from this account": "Получать события календаря от этого аккаунта", + "Grayscale": "Оттенки серого" } diff --git a/translations/zh.json b/translations/zh.json index c378bd5b6..a1886a2c8 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -249,5 +249,6 @@ "Better luck next time": "下次好运", "Unavailable": "不可用", "The server is busy. Please try again later": "服务器忙。 请稍后再试", - "Receive calendar events from this account": "从该帐户接收日历事件" + "Receive calendar events from this account": "从该帐户接收日历事件", + "Grayscale": "灰阶" } diff --git a/webinterface.py b/webinterface.py index c14bd634a..d7e86d6cd 100644 --- a/webinterface.py +++ b/webinterface.py @@ -1243,6 +1243,15 @@ def htmlEditProfile(translate: {}, baseDir: str, path: str, themes = getThemesList() themesDropdown = '
' themesDropdown += ' ' + translate['Theme'] + '
' + grayscaleFilename = \ + baseDir + '/accounts/.grayscale' + grayscale = '' + if os.path.isfile(grayscaleFilename): + grayscale = 'checked' + themesDropdown += \ + ' ' + translate['Grayscale'] + '
' themesDropdown += '