diff --git a/epicyon-login.css b/epicyon-login.css index 09b583a2f..d547f5821 100644 --- a/epicyon-login.css +++ b/epicyon-login.css @@ -129,13 +129,6 @@ span.psw { body, html { background-color: var(--main-bg-color); color: var(--main-fg-color); - - background-image: url("/login-background.jpg"); - background-size: cover; - -webkit-background-size: cover; - -moz-background-size: cover; - background-repeat: no-repeat; - background-position: center; height: 100%; font-family: Arial, Helvetica, sans-serif; max-width: 60%; @@ -144,7 +137,6 @@ span.psw { font-size: var(--font-size); font-family: Arial, Helvetica, sans-serif; position: relative; - top: 3%; } .login-text { font-size: var(--font-size); @@ -177,13 +169,6 @@ span.psw { body, html { background-color: var(--main-bg-color); color: var(--main-fg-color); - - background-image: url("/login-background.jpg"); - background-size: cover; - -webkit-background-size: cover; - -moz-background-size: cover; - background-repeat: no-repeat; - background-position: center; height: 100%; font-family: Arial, Helvetica, sans-serif; max-width: 95%; @@ -192,7 +177,6 @@ span.psw { font-size: var(--font-size-mobile); font-family: Arial, Helvetica, sans-serif; position: relative; - top: 5%; } .login-text { font-size: var(--font-size-mobile); diff --git a/epicyon-options.css b/epicyon-options.css index 1e7c24c49..921fe849a 100644 --- a/epicyon-options.css +++ b/epicyon-options.css @@ -54,7 +54,6 @@ body, html { font-family: Arial, Helvetica, sans-serif; max-width: 100%; min-width: 600px; - margin: 5% auto; } a, u { @@ -89,40 +88,15 @@ a:link { min-width: 200px; } -.followText { - font-size: var(--font-size); - font-family: Arial, Helvetica, sans-serif; -} - .imText { font-size: var(--font-size4); - font-family: Arial, Helvetica, sans-serif; color: var(--main-link-color); - background: var(--link-bg-color); } .pgp { font-size: var(--font-size5); - font-family: Arial, Helvetica, sans-serif; color: var(--main-link-color); background: var(--link-bg-color); - font-family: 'monospace'; -} - -.button { - border-radius: 4px; - background-color: var(--button-background); - border: none; - color: var(--button-text); - text-align: center; - padding: 10px; - font-size: var(--font-size); - font-family: Arial, Helvetica, sans-serif; - width: 20%; - max-width: 200px; - min-width: 100px; - cursor: pointer; - margin: 30px; } .button:hover { @@ -130,19 +104,8 @@ a:link { color: white; } -input[type=text] { - width: var(--follow-text-entry-width); - clear: both; - font-size: var(--font-size); - font-family: Arial, Helvetica, sans-serif; - text-align: center; - color: var(--text-entry-foreground); - background-color: var(--text-entry-background); -} - .options { font-size: var(--font-size); - font-family: Arial, Helvetica, sans-serif; } .options img { @@ -152,26 +115,25 @@ input[type=text] { @media screen and (min-width: 400px) { .followText { font-size: var(--follow-text-size1); - font-family: Arial, Helvetica, sans-serif; } input[type=text] { width: var(--follow-text-entry-width); clear: both; font-size: 24px; - font-family: Arial, Helvetica, sans-serif; text-align: center; color: var(--text-entry-foreground); background-color: var(--text-entry-background); + font-family: Arial, Helvetica, sans-serif; } .button { border-radius: 4px; background-color: var(--button-background); + font-family: Arial, Helvetica, sans-serif; border: none; color: var(--button-text); text-align: center; padding: 10px; font-size: 24px; - font-family: Arial, Helvetica, sans-serif; width: 20%; max-width: 200px; min-width: 100px; @@ -180,39 +142,38 @@ input[type=text] { } input[type=checkbox] { - -ms-transform: scale(2); - -moz-transform: scale(2); - -webkit-transform: scale(2); - -o-transform: scale(2); - transform: scale(2); - padding: 10px; - margin: 20px 30px; + -ms-transform: scale(2); + -moz-transform: scale(2); + -webkit-transform: scale(2); + -o-transform: scale(2); + transform: scale(2); + padding: 10px; + margin: 20px 30px; } } @media screen and (max-width: 1000px) { .followText { font-size: var(--follow-text-size2); - font-family: Arial, Helvetica, sans-serif; } input[type=text] { width: var(--follow-text-entry-width); clear: both; font-size: 40px; - font-family: Arial, Helvetica, sans-serif; text-align: center; color: var(--text-entry-foreground); background-color: var(--text-entry-background); + font-family: Arial, Helvetica, sans-serif; } .button { border-radius: 4px; background-color: var(--button-background); + font-family: Arial, Helvetica, sans-serif; border: none; color: var(--button-text); text-align: center; padding: 10px; font-size: 40px; - font-family: Arial, Helvetica, sans-serif; width: 20%; max-width: 200px; min-width: 100px; diff --git a/epicyon-search.css b/epicyon-search.css new file mode 100644 index 000000000..3df723300 --- /dev/null +++ b/epicyon-search.css @@ -0,0 +1,271 @@ +@charset "UTF-8"; + +:root { + --main-bg-color: #282c37; + --link-bg-color: #282c37; + --main-fg-color: #dddddd; + --main-link-color: #999; + --main-visited-color: #888; + --border-color: #505050; + --font-size-header: 18px; + --font-color-header: #ccc; + --font-size: 40px; + --font-size2: 24px; + --font-size3: 38px; + --font-size4: 22px; + --font-size5: 20px; + --text-entry-foreground: #ccc; + --text-entry-background: #111; + --time-color: #aaa; + --button-text: #FFFFFF; + --button-background: #999; + --button-selected: #666; + --hashtag-margin: 2%; + --hashtag-vertical-spacing1: 50px; + --hashtag-vertical-spacing2: 100px; + --hashtag-vertical-spacing3: 100px; + --hashtag-vertical-spacing4: 150px; + --hashtag-size1: 30px; + --hashtag-size2: 40px; + --follow-text-size1: 24px; + --follow-text-size2: 40px; + --follow-text-entry-width: 90%; +} + +@font-face { + font-family: 'Bedstead'; + font-style: normal; + font-weight: normal; + font-display: block; + src: url('./fonts/bedstead.otf') format('opentype'); +} + +body, html { + background-color: var(--main-bg-color); + color: var(--main-fg-color); + + height: 100%; + font-family: Arial, Helvetica, sans-serif; + max-width: 100%; + min-width: 600px; + margin: 5% auto; +} + +a, u { + color: var(--main-fg-color); +} + +a:visited{ + color: var(--main-visited-color); + background: var(--link-bg-color); + font-weight: bold; +} + +a:link { + color: var(--main-link-color); + background: var(--link-bg-color); + font-weight: bold; +} + +.searchBanner { + background-image: linear-gradient(rgba(0, 0, 0, 0.0), rgba(0, 0, 0, 0.5)), url("search_banner.png"); + background-position: center; + background-repeat: no-repeat; + background-size: 90%; +} + +.follow { + background-image: url("search-background.jpg"); + background-size: cover; + -webkit-background-size: cover; + -moz-background-size: cover; + background-repeat: no-repeat; + background-position: center; + height: 100%; + background-position: center; + background-repeat: no-repeat; + background-size: cover; + position: relative; + background-color: var(--main-bg-color); +} + +.followAvatar { + margin: 0% 0; +} + +.followAvatar img { + border-radius: 10%; + width: 20%; + min-width: 200px; +} + +.followText { + font-size: var(--font-size); + font-family: Arial, Helvetica, sans-serif; +} + +.imText { + font-size: var(--font-size4); + font-family: Arial, Helvetica, sans-serif; + color: var(--main-link-color); + background: var(--link-bg-color); +} + +.pgp { + font-size: var(--font-size5); + font-family: Arial, Helvetica, sans-serif; + color: var(--main-link-color); + background: var(--link-bg-color); + font-family: 'monospace'; +} + +.button { + border-radius: 4px; + background-color: var(--button-background); + border: none; + color: var(--button-text); + text-align: center; + padding: 10px; + font-size: var(--font-size); + font-family: Arial, Helvetica, sans-serif; + width: 20%; + max-width: 200px; + min-width: 100px; + cursor: pointer; + margin: 30px; +} + +.button:hover { + background-color: #555; + color: white; +} + +input[type=text] { + width: var(--follow-text-entry-width); + clear: both; + font-size: var(--font-size); + font-family: Arial, Helvetica, sans-serif; + text-align: center; + color: var(--text-entry-foreground); + background-color: var(--text-entry-background); +} + +.cwButton { + border-radius: 4px; + background-color: #999; + border: none; + color: var(--button-text); + text-align: center; + font-size: var(--font-size); + font-family: Arial, Helvetica, sans-serif; + padding: 2px; + cursor: pointer; + margin: 5px; +} + +.cwText { + display: none; +} + +.options { + font-size: var(--font-size); + font-family: Arial, Helvetica, sans-serif; +} + +.options img { + width: 15%; +} + +@media screen and (min-width: 400px) { + .hashtagswarm { + font-size: var(--hashtag-size1); + font-family: Arial, Helvetica, sans-serif; + margin: var(--hashtag-margin); + line-height: var(--hashtag-vertical-spacing1); + } + .followText { + font-size: var(--follow-text-size1); + font-family: Arial, Helvetica, sans-serif; + } + input[type=text] { + width: var(--follow-text-entry-width); + clear: both; + font-size: 24px; + font-family: Arial, Helvetica, sans-serif; + text-align: center; + color: var(--text-entry-foreground); + background-color: var(--text-entry-background); + } + .button { + border-radius: 4px; + background-color: var(--button-background); + border: none; + color: var(--button-text); + text-align: center; + padding: 10px; + font-size: 24px; + font-family: Arial, Helvetica, sans-serif; + width: 20%; + max-width: 200px; + min-width: 100px; + cursor: pointer; + margin: 30px; + } + input[type=checkbox] + { + -ms-transform: scale(2); + -moz-transform: scale(2); + -webkit-transform: scale(2); + -o-transform: scale(2); + transform: scale(2); + padding: 10px; + margin: 20px 30px; + } +} + +@media screen and (max-width: 1000px) { + .hashtagswarm { + font-size: var(--hashtag-size2); + font-family: Arial, Helvetica, sans-serif; + margin: var(--hashtag-margin); + line-height: var(--hashtag-vertical-spacing3); + } + .followText { + font-size: var(--follow-text-size2); + font-family: Arial, Helvetica, sans-serif; + } + input[type=text] { + width: var(--follow-text-entry-width); + clear: both; + font-size: 40px; + font-family: Arial, Helvetica, sans-serif; + text-align: center; + color: var(--text-entry-foreground); + background-color: var(--text-entry-background); + } + .button { + border-radius: 4px; + background-color: var(--button-background); + border: none; + color: var(--button-text); + text-align: center; + padding: 10px; + font-size: 40px; + font-family: Arial, Helvetica, sans-serif; + width: 20%; + max-width: 200px; + min-width: 100px; + cursor: pointer; + margin: 30px; + } + input[type=checkbox] + { + -ms-transform: scale(4); + -moz-transform: scale(4); + -webkit-transform: scale(4); + -o-transform: scale(4); + transform: scale(4); + padding: 20px; + margin: 30px 40px; + } +} diff --git a/img/login_background_henge.jpg b/img/login_background_henge.jpg new file mode 100644 index 000000000..bd74705cd Binary files /dev/null and b/img/login_background_henge.jpg differ diff --git a/img/login_background_night.jpg b/img/login_background_night.jpg new file mode 100644 index 000000000..98f0d873e Binary files /dev/null and b/img/login_background_night.jpg differ diff --git a/img/login_background_starlight.jpg b/img/login_background_starlight.jpg index de3be58df..f7a3f5dd0 100644 Binary files a/img/login_background_starlight.jpg and b/img/login_background_starlight.jpg differ diff --git a/img/login_background_zen.jpg b/img/login_background_zen.jpg new file mode 100644 index 000000000..e436ea975 Binary files /dev/null and b/img/login_background_zen.jpg differ diff --git a/img/options_background_henge.jpg b/img/options_background_henge.jpg new file mode 100644 index 000000000..1d6649a3f Binary files /dev/null and b/img/options_background_henge.jpg differ diff --git a/img/options_background_night.jpg b/img/options_background_night.jpg new file mode 100644 index 000000000..465669c5f Binary files /dev/null and b/img/options_background_night.jpg differ diff --git a/img/options_background_starlight.jpg b/img/options_background_starlight.jpg index de3be58df..9c82cf81a 100644 Binary files a/img/options_background_starlight.jpg and b/img/options_background_starlight.jpg differ diff --git a/img/options_background_zen.jpg b/img/options_background_zen.jpg new file mode 100644 index 000000000..2ba110aa4 Binary files /dev/null and b/img/options_background_zen.jpg differ diff --git a/img/search_background_starlight.jpg b/img/search_background_starlight.jpg new file mode 100644 index 000000000..dcbfda6ce Binary files /dev/null and b/img/search_background_starlight.jpg differ diff --git a/theme.py b/theme.py index b9a283fb3..a1fc7908f 100644 --- a/theme.py +++ b/theme.py @@ -15,7 +15,7 @@ from shutil import copyfile def getThemeFiles() -> []: return ('epicyon.css', 'login.css', 'follow.css', 'suspended.css', 'calendar.css', 'blog.css', - 'options.css') + 'options.css', 'search.css') def getThemesList() -> []: @@ -113,9 +113,11 @@ def setThemeFromDict(baseDir: str, name: str, if bgParams.get('login'): setBackgroundFormat(baseDir, name, 'login', bgParams['login']) if bgParams.get('follow'): - setBackgroundFormat(baseDir, name, 'login', bgParams['follow']) + setBackgroundFormat(baseDir, name, 'follow', bgParams['follow']) if bgParams.get('options'): - setBackgroundFormat(baseDir, name, 'login', bgParams['options']) + setBackgroundFormat(baseDir, name, 'options', bgParams['options']) + if bgParams.get('search'): + setBackgroundFormat(baseDir, name, 'search', bgParams['search']) def setBackgroundFormat(baseDir: str, name: str, @@ -224,9 +226,10 @@ def setThemeDefault(baseDir: str): "dummyValue": "1234" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -258,9 +261,10 @@ def setThemeBlue(baseDir: str): "*src": "url('./fonts/Domestic_Manners.woff2') format('woff2')" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -302,9 +306,10 @@ def setThemeNight(baseDir: str): "*src": fontStr } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -355,9 +360,10 @@ def setThemeStarlight(baseDir: str): "*src": "url('fonts/bgrove.woff2') format('woff2')" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -405,9 +411,10 @@ def setThemeHenge(baseDir: str): "*src": "url('fonts/bgrove.woff2') format('woff2')" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -435,9 +442,10 @@ def setThemeZen(baseDir: str): "dropdown-bg-color-hover": "#444" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -461,9 +469,10 @@ def setThemeHighVis(baseDir: str): "*src": "url('./fonts/LinBiolinum_Rah.woff2') format('woff2')" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -523,9 +532,10 @@ def setThemeLCD(baseDir: str): "*src": "url('./fonts/LcdSolid.woff2') format('woff2')" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -572,9 +582,10 @@ def setThemePurple(baseDir: str): "*src": fontStr } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -617,9 +628,10 @@ def setThemeHacker(baseDir: str): "image-corners": "0%" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) @@ -669,9 +681,10 @@ def setThemeLight(baseDir: str): "*src": "url('./fonts/ElectrumADFExp-Regular.otf') format('opentype')" } bgParams = { - "login": 'jpg', - "follow": 'jpg', - "options": 'jpg' + "login": "jpg", + "follow": "jpg", + "options": "jpg", + "search": "jpg" } setThemeFromDict(baseDir, name, themeParams, bgParams) diff --git a/webinterface.py b/webinterface.py index 5095074d1..762b7f67a 100644 --- a/webinterface.py +++ b/webinterface.py @@ -1641,35 +1641,36 @@ def htmlLogin(translate: {}, baseDir: str, autocomplete=True) -> str: autocompleteStr = 'autocomplete="off" value=""' loginForm = htmlHeader(cssFilename, loginCSS) - loginForm += '
' - loginForm += '
' + loginForm += '
\n' + loginForm += '\n' + loginForm += '
\n' loginForm += \ ' login image' - loginForm += loginText + TOSstr - loginForm += '
' - loginForm += '' - loginForm += '
' + '" alt="login image" class="loginimage">\n' + loginForm += loginText + TOSstr + '\n' + loginForm += '
\n' + loginForm += '\n' + loginForm += '
\n' loginForm += ' ' + translate['Nickname'] + '\n' loginForm += \ ' ' - loginForm += '' + translate['Enter Nickname'] + '" name="username" required autofocus>\n' + loginForm += '\n' loginForm += ' ' + translate['Password'] + '\n' loginForm += \ ' ' - loginForm += loginButtonStr + registerButtonStr - loginForm += '
' - loginForm += '' + '" name="password" required>\n' + loginForm += loginButtonStr + registerButtonStr + '\n' + loginForm += '
\n' + loginForm += '\n' loginForm += \ '' + \ '' + \
-        translate['Get the source code'] + '' + translate['Get the source code'] + '" src="/icons/agpl.png" />\n' loginForm += htmlFooter() return loginForm @@ -1702,14 +1703,15 @@ def htmlTermsOfService(baseDir: str, httpPrefix: str, domainFull: str) -> str: termsCSS = termsCSS.replace('https://', httpPrefix+'://') TOSForm = htmlHeader(cssFilename, termsCSS) - TOSForm += '
' + TOSText + '
' + TOSForm += '
' + TOSText + '
\n' if adminNickname: adminActor = httpPrefix + '://' + domainFull + \ '/users/' + adminNickname TOSForm += \ - '
' + \ + '
\n' + \ '

Administered by ' + adminNickname + '

' + adminActor + '">' + adminNickname + '

\n' + \ + '
\n' TOSForm += htmlFooter() return TOSForm @@ -1747,14 +1749,16 @@ def htmlAbout(baseDir: str, httpPrefix: str, aboutForm += '
' + aboutText + '
' if onionDomain: aboutForm += \ - '

' + \ - 'http://' + onionDomain + '

' + '
\n' + \ + '

' + \ + 'http://' + onionDomain + '

\n
\n' if adminNickname: adminActor = '/users/' + adminNickname aboutForm += \ - '
' + \ + '
\n' + \ '

Administered by ' + adminNickname + '

' + adminActor + '">' + adminNickname + '

\n' + \ + '
\n' aboutForm += htmlFooter() return aboutForm @@ -1769,11 +1773,11 @@ def htmlHashtagBlocked(baseDir: str) -> str: with open(cssFilename, 'r') as cssFile: blockedHashtagCSS = cssFile.read() blockedHashtagForm = htmlHeader(cssFilename, blockedHashtagCSS) - blockedHashtagForm += '
' - blockedHashtagForm += '

Hashtag Blocked

' + blockedHashtagForm += '
\n' + blockedHashtagForm += '

Hashtag Blocked

\n' blockedHashtagForm += \ - '

See Terms of Service

' - blockedHashtagForm += '
' + '

See Terms of Service

\n' + blockedHashtagForm += '
\n' blockedHashtagForm += htmlFooter() return blockedHashtagForm @@ -1788,10 +1792,10 @@ def htmlSuspended(baseDir: str) -> str: with open(cssFilename, 'r') as cssFile: suspendedCSS = cssFile.read() suspendedForm = htmlHeader(cssFilename, suspendedCSS) - suspendedForm += '
' - suspendedForm += '

Account Suspended

' - suspendedForm += '

See Terms of Service

' - suspendedForm += '
' + suspendedForm += '
\n' + suspendedForm += '

Account Suspended

\n' + suspendedForm += '

See Terms of Service

\n' + suspendedForm += '
\n' suspendedForm += htmlFooter() return suspendedForm @@ -1814,13 +1818,13 @@ def htmlNewPost(mediaInstance: bool, translate: {}, if not path.endswith('/newreport'): if not inReplyTo or path.endswith('/newreminder'): newPostText = '

' + \ - translate['Write your post text below.'] + '

' + translate['Write your post text below.'] + '

\n' else: newPostText = \ '

' + \ translate['Write your reply to'] + \ ' ' + \ - translate['this post'] + '

' + translate['this post'] + '

\n' replyStr = '' @@ -1839,7 +1843,7 @@ def htmlNewPost(mediaInstance: bool, translate: {}, else: newPostText = \ '

' + \ - translate['Write your report below.'] + '

' + translate['Write your report below.'] + '

\n' # custom report header with any additional instructions if os.path.isfile(baseDir + '/accounts/report.txt'): @@ -1848,7 +1852,7 @@ def htmlNewPost(mediaInstance: bool, translate: {}, if '

' not in customReportText: customReportText = \ '

' + \ - customReportText + '

' + customReportText + '

\n' repStr = '

' customReportText = \ customReportText.replace('

', repStr) @@ -1857,24 +1861,26 @@ def htmlNewPost(mediaInstance: bool, translate: {}, idx = 'This message only goes to moderators, even if it ' + \ 'mentions other fediverse addresses.' newPostText += \ - '

' + translate[idx] + \ - '

' + translate['Also see'] + \ + '

' + translate[idx] + '

\n' + \ + '

' + translate['Also see'] + \ ' ' + \ - translate['Terms of Service'] + '

' + translate['Terms of Service'] + '

\n' else: newPostText = \ '

' + \ - translate['Enter the details for your shared item below.'] + '

' + translate['Enter the details for your shared item below.'] + \ + '

\n' if path.endswith('/newquestion'): newPostText = \ '

' + \ - translate['Enter the choices for your question below.'] + '

' + translate['Enter the choices for your question below.'] + \ + '

\n' if os.path.isfile(baseDir + '/accounts/newpost.txt'): with open(baseDir + '/accounts/newpost.txt', 'r') as file: newPostText = \ - '

' + file.read() + '

' + '

' + file.read() + '

\n' cssFilename = baseDir + '/epicyon-profile.css' if os.path.isfile(baseDir + '/epicyon.css'): @@ -1896,14 +1902,15 @@ def htmlNewPost(mediaInstance: bool, translate: {}, newPostImageSection = '
' newPostImageSection += \ ' ' - newPostImageSection += ' ' + '\n' + newPostImageSection += \ + ' \n' newPostImageSection += \ ' ' - newPostImageSection += '
' + '.webm, .ogv, .mp3, .ogg">\n' + newPostImageSection += ' \n' scopeIcon = 'scope_public.png' scopeDescription = translate['Public'] @@ -1947,19 +1954,19 @@ def htmlNewPost(mediaInstance: bool, translate: {}, scopeDescription = translate['Question'] placeholderMessage = translate['Enter your question'] + '...' endpoint = 'newquestion' - extraFields = '
' + extraFields = '
\n' extraFields += '
' + translate['Possible answers'] + ':
\n' for questionCtr in range(8): extraFields += \ '
' + '" name="questionOption' + str(questionCtr) + '">
\n' extraFields += \ '
' + 'min="1" max="365" step="1" value="14">
\n' extraFields += '
' elif path.endswith('/newshare'): scopeIcon = 'scope_share.png' @@ -1968,27 +1975,29 @@ def htmlNewPost(mediaInstance: bool, translate: {}, placeholderMessage = \ translate['Description of the item being shared'] + '...' endpoint = 'newshare' - extraFields = '
' + extraFields = '
\n' extraFields += \ ' ' - extraFields += ' ' + translate['Type of shared item. eg. hat'] + ':\n' + extraFields += \ + ' \n' extraFields += \ '
' - extraFields += ' ' + translate['Category of shared item. eg. clothing'] + ':\n' + extraFields += \ + ' \n' extraFields += \ '
' + translate['Duration of listing in days'] + ':\n' extraFields += ' ' - extraFields += '
' - extraFields += '
' + 'min="1" max="365" step="1" value="14">\n' + extraFields += '
\n' + extraFields += '
\n' extraFields += \ '' - extraFields += '' - extraFields += '
' + translate['City or location of the shared item'] + ':\n' + extraFields += '\n' + extraFields += '
\n' dateAndLocation = '' if endpoint != 'newshare' and \ @@ -2000,24 +2009,24 @@ def htmlNewPost(mediaInstance: bool, translate: {}, dateAndLocation += \ '

' + translate['This is a scheduled post.'] + '

\n' dateAndLocation += \ '

' + iconsDir + '/calendar.png"/>\n' dateAndLocation += '' - dateAndLocation += '' + translate['Date'] + ': \n' + dateAndLocation += '\n' dateAndLocation += '

' - dateAndLocation += '
' - dateAndLocation += '
' + dateAndLocation += '

\n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' dateAndLocation += '
' - dateAndLocation += '' - dateAndLocation += '
' + translate['Location'] + ': \n' + dateAndLocation += '\n' + dateAndLocation += '\n' newPostForm = htmlHeader(cssFilename, newPostCSS) @@ -2342,12 +2351,12 @@ def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str, if authorized and pageNumber > 1: # page up arrow profileStr += \ - '
' + \
-                translate['Page up'] + '
' + translate['Page up'] + '">\n\n' for item in followingJson['orderedItems']: profileStr += \ @@ -2360,12 +2369,12 @@ def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str, if len(followingJson['orderedItems']) >= maxItemsPerPage: # page down arrow profileStr += \ - '
' + \
-                translate['Page down'] + '
' + translate['Page down'] + '">\n\n' return profileStr @@ -2376,16 +2385,16 @@ def htmlProfileRoles(translate: {}, nickname: str, domain: str, profileStr = '' for project, rolesList in rolesJson.items(): profileStr += \ - '

' + project + \ - '

' + '
\n

' + project + \ + '

\n
\n' for role in rolesList: - profileStr += '

' + role + '

' - profileStr += '
' + profileStr += '

' + role + '

\n' + profileStr += '
\n' if len(profileStr) == 0: profileStr += \ - '

@' + nickname + '@' + domain + ' has no roles assigned

' + '

@' + nickname + '@' + domain + ' has no roles assigned

\n' else: - profileStr = '
' + profileStr + '
' + profileStr = '
' + profileStr + '
\n' return profileStr @@ -2398,10 +2407,10 @@ def htmlProfileSkills(translate: {}, nickname: str, domain: str, profileStr += \ '
' + skill + \ '

' + str(level) + '%">\n
\n' if len(profileStr) > 0: profileStr = '
' + \ - profileStr + '
' + profileStr + '\n' return profileStr @@ -2409,33 +2418,33 @@ def htmlIndividualShare(actor: str, item: {}, translate: {}, showContact: bool, removeButton: bool) -> str: """Returns an individual shared item as html """ - profileStr = '
' - profileStr += '

' + item['displayName'] + '

' + profileStr = '
\n' + profileStr += '\n' if item.get('imageUrl'): - profileStr += '' + profileStr += '\n' profileStr += \ '' + translate['Item image'] + '' - profileStr += '

' + item['summary'] + '

' + '" alt="' + translate['Item image'] + '">\n\n' + profileStr += '

' + item['summary'] + '

\n' profileStr += \ '

' + translate['Type'] + ': ' + item['itemType'] + ' ' profileStr += \ '' + translate['Category'] + ': ' + item['category'] + ' ' profileStr += \ - '' + translate['Location'] + ': ' + item['location'] + '

' + '' + translate['Location'] + ': ' + item['location'] + '

\n' if showContact: contactActor = item['actor'] profileStr += \ '

' + translate['Contact'] + '\n' if removeButton: profileStr += \ ' ' - profileStr += '

' + translate['Remove'] + '\n' + profileStr += '
\n' return profileStr @@ -2447,7 +2456,7 @@ def htmlProfileShares(actor: str, translate: {}, for item in sharesJson['orderedItems']: profileStr += htmlIndividualShare(actor, item, translate, False, False) if len(profileStr) > 0: - profileStr = '
' + profileStr + '
' + profileStr = '
' + profileStr + '
\n' return profileStr @@ -2522,11 +2531,11 @@ def htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int, if pageNumber > 1: iconsDir = getIconsDir(baseDir) timelineStr += \ - '
' + translate['Page up'] + '
' + '" alt="' + translate['Page up'] + '">\n\n' for published, item in sharesJson.items(): showContactButton = False @@ -2542,11 +2551,11 @@ def htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int, if not lastPage: iconsDir = getIconsDir(baseDir) timelineStr += \ - '
' + translate['Page down'] + '
' + '" alt="' + translate['Page down'] + '">\n\n' return timelineStr @@ -2886,20 +2895,20 @@ def individualFollowAsHtml(translate: {}, '' + translate['Block'] + '\n' if b == 'unfollow': buttonsStr += \ '' + translate['Unfollow'] + '\n' resultStr = '
\n' resultStr += \ '' - resultStr += '

 \n' - resultStr += titleStr + '' + buttonsStr + '

' + followUrl + ';1;' + avatarUrl + '">\n' + resultStr += '

 ' + resultStr += titleStr + '' + buttonsStr + '

\n' resultStr += '
\n' return resultStr @@ -2939,13 +2948,13 @@ def addEmbeddedAudio(translate: {}, content: str) -> str: '/' in w): continue url = w - content += '
\n
\n' return content @@ -2987,14 +2996,14 @@ def addEmbeddedVideo(translate: {}, content: str, continue url = w content += \ - '
\n
\n' return content @@ -3007,12 +3016,12 @@ def addEmbeddedVideoFromSites(translate: {}, content: str, if '<' in url: url = url.split('<')[0] content = \ - content + "
" + "fullscreen\" allowfullscreen>\n\n" return content videoSite = 'https://www.youtube.com' @@ -3023,11 +3032,11 @@ def addEmbeddedVideoFromSites(translate: {}, content: str, if '&' in url: url = url.split('&')[0] content = \ - content + "
" + "allowfullscreen>\n\n" return content invidiousSites = ('https://invidio.us', @@ -3041,11 +3050,11 @@ def addEmbeddedVideoFromSites(translate: {}, content: str, if '&' in url: url = url.split('&')[0] content = \ - content + "
" + "allowfullscreen>\n\n" return content videoSite = 'https://media.ccc.de' @@ -3056,11 +3065,11 @@ def addEmbeddedVideoFromSites(translate: {}, content: str, if not url.endswith('/oembed'): url = url + '/oembed' content = \ - content + "
" + "allowfullscreen>\n\n" return content if '"https://' in content: @@ -3099,13 +3108,13 @@ def addEmbeddedVideoFromSites(translate: {}, content: str, if '"' in url: url = url.split('"')[0].replace('/watch/', '/embed/') content = \ - content + "
" + "fullscreen\" allowfullscreen>\n\n" return content return content @@ -3162,10 +3171,10 @@ def insertQuestion(baseDir: str, translate: {}, content += '
' content += \ '
' + nickname + '/question' + pageNumberStr + '">\n' content += \ '
' + messageId + '">\n
\n' for choice in postJsonObject['object']['oneOf']: if not choice.get('type'): continue @@ -3173,14 +3182,14 @@ def insertQuestion(baseDir: str, translate: {}, continue content += \ ' ' + choice['name'] + '

' + choice['name'] + '"> ' + choice['name'] + '

\n' content += \ '

' - content += '
' + translate['Vote'] + '" class="vote">

\n' + content += '\n\n' else: # show the responses to a question - content += '
' + content += '
\n' # get the maximum number of votes maxVotes = 1 @@ -3214,14 +3223,14 @@ def insertQuestion(baseDir: str, translate: {}, '

' + ' (' + str(votes) + ')" style="width:40%">\n' content += \ '

' + '" value="' + votesPercent + '">

\n' questionCtr += 1 - content += '
' + content += '
\n' return content @@ -3405,7 +3414,7 @@ def getPostAttachmentsAsHtml(postJsonObject: {}, boxName: str, translate: {}, return attachmentStr, galleryStr attachmentCtr = 0 - attachmentStr += '
' + attachmentStr += '
\n' for attach in postJsonObject['object']['attachment']: if not (attach.get('mediaType') and attach.get('url')): continue @@ -3570,7 +3579,7 @@ def getPostAttachmentsAsHtml(postJsonObject: {}, boxName: str, translate: {}, galleryStr += '
\n' galleryStr += '
\n' - attachmentStr += '
\n
\n' attachmentCtr += 1 attachmentStr += '' return attachmentStr, galleryStr @@ -3684,13 +3693,13 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, fullDomain + '/users/' + nickname not in postActor: avatarLink = \ ' ' + ';' + str(pageNumber) + ';' + avatarUrl + messageIdStr + '">\n' avatarLink += \ ' ' + '" src="' + avatarUrl + '" ' + avatarPosition + '/>\n' avatarImageInPost = \ - '
' + avatarLink + '
' + '
' + avatarLink + '
\n' # don't create new html within the bookmarks timeline # it should already have been created for the inbox @@ -3756,7 +3765,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, titleStr += \ '' + displayName + '' + '">' + displayName + '\n' else: if not messageId: # pprint(postJsonObject) @@ -3770,13 +3779,13 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, titleStr += \ '@' + actorNickname + '@' + actorDomain + '' + '">@' + actorNickname + '@' + actorDomain + '\n' # Show a DM icon for DMs in the inbox timeline if showDMicon: titleStr = \ titleStr + ' ' + iconsDir + '/dm.png" class="DMicon"/>\n' replyStr = '' if showIcons: @@ -3800,26 +3809,26 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, replyStr += \ '' + '" title="' + translate['Reply to this post'] + '">\n' else: if isDM(postJsonObject): replyStr += \ '' + '" title="' + translate['Reply to this post'] + '">\n' else: replyStr += \ '' + '" title="' + translate['Reply to this post'] + '">\n' replyStr += \ '' + \
             translate['Reply to this post'] + \
-            ' |' + ' |" src="/' + iconsDir + '/reply.png"/>\n' editStr = '' if fullDomain + '/users/' + nickname in postJsonObject['actor']: @@ -3834,7 +3843,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, '' + \
                     translate['Edit blog post'] + \
-                    ' |' + ' |" src="/' + iconsDir + '/edit.png"/>\n' announceStr = '' if not isModerationPost and showRepeatIcon: @@ -3854,11 +3863,11 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, '=' + postJsonObject['object']['id'] + pageNumberParam + \ '?actor=' + postJsonObject['actor'] + \ '?bm=' + timelinePostBookmark + \ - '?tl=' + boxName + '" title="' + announceTitle + '">' + '?tl=' + boxName + '" title="' + announceTitle + '">\n' announceStr += \ '' + translate['Repeat this post'] + \
-            ' |' + ' |" src="/' + iconsDir + '/' + announceIcon + '"/>\n' likeStr = '' if not isModerationPost: @@ -3884,11 +3893,11 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, '?actor=' + postJsonObject['actor'] + \ '?bm=' + timelinePostBookmark + \ '?tl=' + boxName + '" title="' + \ - likeTitle + likeCountStr + '">' + likeTitle + likeCountStr + '">\n' likeStr += \ '' + likeTitle + \
-            ' |' + ' |" src="/' + iconsDir + '/' + likeIcon + '"/>\n' bookmarkStr = '' if not isModerationPost: @@ -3905,11 +3914,11 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, pageNumberParam + \ '?actor=' + postJsonObject['actor'] + \ '?bm=' + timelinePostBookmark + \ - '?tl=' + boxName + '" title="' + bookmarkTitle + '">' + '?tl=' + boxName + '" title="' + bookmarkTitle + '">\n' bookmarkStr += \ '' + \
             bookmarkTitle + ' |' + '/' + bookmarkIcon + '"/>\n' isMuted = postIsMuted(baseDir, nickname, domain, postJsonObject, messageId) @@ -3922,33 +3931,33 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, deleteStr = \ '' + '" title="' + translate['Delete this post'] + '">\n' deleteStr += \ '' + translate['Delete this post'] + \
                 ' |' + '" src="/' + iconsDir + '/delete.png"/>\n' else: if not isMuted: muteStr = \ '' + '" title="' + translate['Mute this post'] + '">\n' muteStr += \ '' + \
                 translate['Mute this post'] + \
                 ' |' + '" src="/' + iconsDir + '/mute.png"/>\n' else: muteStr = \ '' + translate['Undo mute'] + '">\n' muteStr += \ '' + translate['Undo mute'] + \
                 ' |' + '" src="/' + iconsDir+'/unmute.png"/>\n' replyAvatarImageInPost = '' if showRepeatIcon: @@ -3961,7 +3970,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, translate['announces'] + \ '" alt="' + translate['announces'] + \ '" src="/' + iconsDir + \ - '/repeat_inactive.png" class="announceOrReply"/>' + '/repeat_inactive.png" class="announceOrReply"/>\n' else: announceNickname = \ getNicknameFromActor(attributedTo) @@ -3985,7 +3994,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, iconsDir + '/repeat_inactive.png" ' + \ 'class="announceOrReply"/> ' + \ - announceDisplayName + '' + announceDisplayName + '\n' # show avatar of person replied to announceActor = \ postJsonObject['object']['attributedTo'] @@ -3995,7 +4004,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, if announceAvatarUrl: idx = 'Show options for this person' replyAvatarImageInPost = \ - '
' \ + '
\n' \ '
' + '/>\n
\n' else: titleStr += \ ' @' + \ announceNickname + '@' + \ - announceDomain + '' + announceDomain + '\n' else: titleStr += \ ' @unattributed' + '">@unattributed\n' else: titleStr += \ ' @unattributed' + postJsonObject['object']['id'] + '">@unattributed\n' else: if postJsonObject['object'].get('inReplyTo'): containerClassIcons = 'containericons darker' @@ -4044,7 +4053,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, translate['replying to themselves'] + \ '" alt="' + translate['replying to themselves'] + \ '" src="/' + iconsDir + \ - '/reply.png" class="announceOrReply"/>' + '/reply.png" class="announceOrReply"/>\n' else: if '/statuses/' in postJsonObject['object']['inReplyTo']: inReplyTo = postJsonObject['object']['inReplyTo'] @@ -4078,7 +4087,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, iconsDir + '/reply.png" ' + \ 'class="announceOrReply"/> ' + \ '' + replyDisplayName + '' + '">' + replyDisplayName + '\n' # show avatar of person replied to replyAvatarUrl = \ @@ -4088,13 +4097,13 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, if replyAvatarUrl: replyAvatarImageInPost = \ '
' + '"timeline-avatar-reply">\n' replyAvatarImageInPost += \ '' + messageIdStr + '">\n' replyAvatarImageInPost += \ '
' + avatarPosition + '/>\n\n' else: inReplyTo = \ postJsonObject['object']['inReplyTo'] @@ -4118,7 +4127,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, '@' + \ replyNickname + '@' + \ - replyDomain + '' + replyDomain + '\n' else: titleStr += \ ' ' + \ '@unknown' + '">@unknown\n' else: postDomain = \ postJsonObject['object']['inReplyTo'] @@ -4148,7 +4157,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, iconsDir + '/reply.png" ' + \ 'class="announceOrReply"/> ' + postDomain + '' + '">' + postDomain + '\n' attachmentStr, galleryStr = \ getPostAttachmentsAsHtml(postJsonObject, boxName, translate, @@ -4246,7 +4255,7 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, contentStr = '' if postJsonObject['object'].get('summary'): contentStr += \ - '' + postJsonObject['object']['summary'] + ' ' + '' + postJsonObject['object']['summary'] + '\n ' if isModerationPost: containerClass = 'container report' # get the content warning text @@ -4273,11 +4282,11 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, contentStr = '' else: if not isPatch: - contentStr = '
' + contentStr + '
' + contentStr = '
' + contentStr + '
\n' else: contentStr = \ '
' + contentStr + \
-                '
' + '\n' postHtml = '' if boxName != 'tlmedia': @@ -4285,8 +4294,8 @@ def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int, '" class="' + containerClass + '">\n' postHtml += avatarImageInPost postHtml += '

' + titleStr + \ - replyAvatarImageInPost + '

' - postHtml += contentStr + footerStr + replyAvatarImageInPost + '

\n' + postHtml += contentStr + footerStr + '\n' postHtml += '\n' else: postHtml = galleryStr @@ -4488,7 +4497,7 @@ def htmlTimeline(defaultTimeline: str, 'class="timelineicon" alt="' + \ translate['Approve follow requests'] + \ '" title="' + translate['Approve follow requests'] + \ - '" src="/' + iconsDir + '/person.png"/>' + '" src="/' + iconsDir + '/person.png"/>\n' break moderationButtonStr = '' @@ -4498,7 +4507,7 @@ def htmlTimeline(defaultTimeline: str, '/moderation">' + ' \n' sharesButtonStr = '' bookmarksButtonStr = '' @@ -4507,12 +4516,12 @@ def htmlTimeline(defaultTimeline: str, '' + ' \n' bookmarksButtonStr = \ '' + ' \n' tlStr = htmlHeader(cssFilename, profileStyle) @@ -4525,7 +4534,7 @@ def htmlTimeline(defaultTimeline: str, iconsDir + '/newpost.png" title="' + \ translate['Create a new post'] + '" alt="| ' + \ translate['Create a new post'] + \ - '" class="timelineicon"/>' + '" class="timelineicon"/>\n' else: newPostButtonStr = \ '' + '" class="timelineicon"/>\n' else: newPostButtonStr = \ '' + '" class="timelineicon"/>\n' else: newPostButtonStr = \ '' + '" class="timelineicon"/>\n' # This creates a link to the profile page when viewed # in lynx, but should be invisible in a graphical web browser tlStr += \ '' + translate['Switch to profile view'] + '\n' # banner and row of buttons tlStr += \ '' + translate['Switch to profile view'] + '">\n' tlStr += '
' - tlStr += '
' + tlStr += '\n\n' tlStr += '
\n' # first button @@ -4572,30 +4581,30 @@ def htmlTimeline(defaultTimeline: str, ' ' + '\n' elif defaultTimeline == 'tlblogs': tlStr += \ ' ' + '\n' else: tlStr += \ ' ' + translate['Inbox'] + '\n' tlStr += \ ' ' + '\n' tlStr += \ ' ' + '\n' # typically the media button if defaultTimeline != 'tlmedia': @@ -4604,14 +4613,14 @@ def htmlTimeline(defaultTimeline: str, ' ' + '\n' else: if not minimal: tlStr += \ ' ' + '\n' # typically the blogs button if defaultTimeline != 'tlblogs': @@ -4620,20 +4629,20 @@ def htmlTimeline(defaultTimeline: str, ' ' + '\n' else: if not minimal: tlStr += \ ' ' + '\n' tlStr += \ ' ' + '\n' tlStr += \ sharesButtonStr + bookmarksButtonStr + \ moderationButtonStr + newPostButtonStr @@ -4642,7 +4651,7 @@ def htmlTimeline(defaultTimeline: str, '/search">| ' + \
-        translate['Search and follow'] + '' + translate['Search and follow'] + '" class="timelineicon"/>\n' calendarAltText = translate['Calendar'] if newCalendarEvent: @@ -4652,14 +4661,14 @@ def htmlTimeline(defaultTimeline: str, ' | ' + calendarAltText + '' + '" alt="| ' + calendarAltText + '" class="timelineicon"/>\n' tlStr += \ ' | ' + translate['Show/Hide Buttons'] + \
-        '' + '" class="timelineicon"/>\n' tlStr += followApprovals tlStr += '
' @@ -4678,29 +4687,29 @@ def htmlTimeline(defaultTimeline: str, ' ' + translate['Remove'] + '">\n' tlStr += \ ' ' + '" name="submitSuspend" value="' + translate['Suspend'] + '">\n' tlStr += \ ' ' + translate['Unsuspend'] + '">\n' tlStr += \ ' ' + '" name="submitBlock" value="' + translate['Block'] + '">\n' tlStr += \ ' ' + '" name="submitUnblock" value="' + translate['Unblock'] + '">\n' tlStr += \ ' ' - tlStr += '' + '" name="submitInfo" value="' + translate['Info'] + '">\n' + tlStr += '\n\n' if boxName == 'tlshares': maxSharesPerAccount = itemsPerPage @@ -4715,32 +4724,33 @@ def htmlTimeline(defaultTimeline: str, if todaysEventsCheck(baseDir, nickname, domain): now = datetime.now() tlStr += \ - '
' + translate['Happening Today'] + '\n' if thisWeeksEventsCheck(baseDir, nickname, domain): tlStr += \ '' - tlStr += '
' + translate['Happening This Week'] + '\n' + tlStr += '\n' else: if thisWeeksEventsCheck(baseDir, nickname, domain): tlStr += \ - '
' + translate['Happening This Week'] + '\n' + \ + '\n' # page up arrow if pageNumber > 1: tlStr += \ - '
' + \
-            translate['Page up'] + '
' + translate['Page up'] + '">\n\n' # show the posts itemCtr = 0 @@ -4797,12 +4807,12 @@ def htmlTimeline(defaultTimeline: str, # page down arrow if itemCtr > 2: tlStr += \ - '
' + \
-            translate['Page down'] + '
' + translate['Page down'] + '">\n\n' tlStr += htmlFooter() return tlStr @@ -4999,7 +5009,7 @@ def htmlIndividualPost(recentPostsCache: {}, maxRecentPosts: int, postStr += \ '

' + translate['Liked by'] + \ ' @' + \ - likedByHandle + '' + likedByHandle + '\n' domainFull = domain if port: @@ -5007,18 +5017,18 @@ def htmlIndividualPost(recentPostsCache: {}, maxRecentPosts: int, domainFull = domain + ':' + str(port) actor = '/users/' + nickname followStr = '

' + 'accept-charset="UTF-8" action="' + actor + '/searchhandle">\n' followStr += \ - ' ' + ' \n' followStr += \ ' ' + likedByHandle + '">\n' if not isFollowingActor(baseDir, nickname, domainFull, likedBy): followStr += ' ' + 'name="submitSearch">' + translate['Follow'] + '\n' followStr += ' ' - followStr += '
' + 'name="submitBack">' + translate['Go Back'] + '\n' + followStr += ' \n' postStr += followStr + '

\n' postStr += \ @@ -5159,30 +5169,31 @@ def htmlRemoveSharedItem(translate: {}, baseDir: str, with open(cssFilename, 'r') as cssFile: profileStyle = cssFile.read() sharesStr = htmlHeader(cssFilename, profileStyle) - sharesStr += '
' - sharesStr += '
' - sharesStr += '
' + sharesStr += '' + translate['No'] + '\n' + sharesStr += ' \n' + sharesStr += '
\n' + sharesStr += '
\n' + sharesStr += '
\n' sharesStr += htmlFooter() return sharesStr @@ -5244,21 +5255,21 @@ def htmlDeletePost(recentPostsCache: {}, maxRecentPosts: int, postActor = getAltPath(actor, domainFull, callingDomain) deletePostStr += \ - '
' + ' \n' deletePostStr += \ ' ' + str(pageNumber) + '">\n' deletePostStr += \ ' ' + messageId + '">\n' deletePostStr += \ ' ' + translate['Yes'] + '\n' deletePostStr += \ ' ' - deletePostStr += '
' - deletePostStr += '' + translate['No'] + '\n' + deletePostStr += ' \n' + deletePostStr += '\n' deletePostStr += htmlFooter() return deletePostStr @@ -5308,28 +5319,28 @@ def htmlCalendarDeleteConfirm(translate: {}, baseDir: str, postActor = getAltPath(actor, domainFull, callingDomain) deletePostStr += \ - '
' + ' \n' deletePostStr += ' ' + str(year) + '">\n' deletePostStr += ' ' + str(monthNumber) + '">\n' deletePostStr += ' ' + str(dayNumber) + '">\n' deletePostStr += \ - ' ' + ' \n' deletePostStr += \ ' ' + messageId + '">\n' deletePostStr += \ ' ' + translate['Yes'] + '\n' deletePostStr += \ ' ' - deletePostStr += '
' - deletePostStr += '' + translate['No'] + '\n' + deletePostStr += ' \n' + deletePostStr += '\n' deletePostStr += htmlFooter() return deletePostStr @@ -5353,28 +5364,28 @@ def htmlFollowConfirm(translate: {}, baseDir: str, with open(cssFilename, 'r') as cssFile: profileStyle = cssFile.read() followStr = htmlHeader(cssFilename, profileStyle) - followStr += '
' - followStr += '
' - followStr += '
' - followStr += ' ' - followStr += ' ' + followStr += '' + translate['No'] + '\n' + followStr += ' \n' + followStr += '
\n' + followStr += '
\n' + followStr += '
\n' followStr += htmlFooter() return followStr @@ -5398,28 +5409,29 @@ def htmlUnfollowConfirm(translate: {}, baseDir: str, with open(cssFilename, 'r') as cssFile: profileStyle = cssFile.read() followStr = htmlHeader(cssFilename, profileStyle) - followStr += '
' - followStr += '
' - followStr += '
' - followStr += ' ' - followStr += ' ' + followStr += '' + translate['No'] + '\n' + followStr += ' \n' + followStr += '
\n' + followStr += '
\n' + followStr += '
\n' followStr += htmlFooter() return followStr @@ -5500,9 +5512,10 @@ def htmlPersonOptions(translate: {}, baseDir: str, donateStr = \ ' ' + translate['Donate'] + '\n' optionsStr = htmlHeader(cssFilename, profileStyle) + optionsStr += '

\n' optionsStr += '
\n' optionsStr += '
\n' optionsStr += '
\n' @@ -5628,28 +5641,28 @@ def htmlUnblockConfirm(translate: {}, baseDir: str, with open(cssFilename, 'r') as cssFile: profileStyle = cssFile.read() blockStr = htmlHeader(cssFilename, profileStyle) - blockStr += '
' - blockStr += '
' - blockStr += '
' - blockStr += ' ' - blockStr += ' ' + blockStr += '
\n' + blockStr += '
\n' + blockStr += '
\n' + blockStr += ' \n' + blockStr += ' \n' blockStr += \ '

' + translate['Stop blocking'] + ' ' + \ - getNicknameFromActor(blockActor) + '@' + blockDomain + ' ?

' + getNicknameFromActor(blockActor) + '@' + blockDomain + ' ?

\n' blockStr += '
' + originPathStr + '/unblockconfirm">\n' blockStr += ' ' + blockActor + '">\n' blockStr += \ ' ' + translate['Yes'] + '\n' blockStr += \ ' ' - blockStr += '
' - blockStr += '
' - blockStr += '
' - blockStr += '
' + translate['No'] + '\n' + blockStr += ' \n' + blockStr += '
\n' + blockStr += '
\n' + blockStr += '
\n' blockStr += htmlFooter() return blockStr @@ -5678,24 +5691,24 @@ def htmlSearchEmojiTextEntry(translate: {}, with open(cssFilename, 'r') as cssFile: profileStyle = cssFile.read() emojiStr = htmlHeader(cssFilename, profileStyle) - emojiStr += '\n' emojiStr += htmlFooter() return emojiStr @@ -5735,7 +5748,7 @@ def htmlCalendarDay(translate: {}, calendarStr += '\n' calendarStr += \ ' ' + '?month=' + str(monthNumber) + '">\n' calendarStr += \ '

' + str(dayNumber) + ' ' + monthName + \ '


' + str(year) + '\n' @@ -5773,10 +5786,10 @@ def htmlCalendarDay(translate: {}, '/eventdelete?id=' + postId + '?year=' + str(year) + \ '?month=' + str(monthNumber) + '?day=' + str(dayNumber) + \ '?time=' + eventTime + \ - '">' + \
+                    '\n' + \
                     translate['Delete this event'] + ' |' + iconsDir + '/delete.png" />\n' if eventTime and eventDescription and eventPlace: calendarStr += \ @@ -6105,7 +6118,7 @@ def htmlHashTagSwarm(baseDir: str, actor: str) -> str: for tagName in tagSwarm: tagSwarmStr += \ '' + tagName + ' ' + '" class="hashtagswarm">' + tagName + '\n' ctr += 1 tagSwarmHtml = tagSwarmStr.strip() + '\n' return tagSwarmHtml @@ -6123,7 +6136,7 @@ def htmlSearch(translate: {}, copyfile(baseDir + '/img/search-background.png', baseDir + '/accounts/search-background.png') - cssFilename = baseDir + '/epicyon-follow.css' + cssFilename = baseDir + '/epicyon-search.css' if os.path.isfile(baseDir + '/follow.css'): cssFilename = baseDir + '/follow.css' with open(cssFilename, 'r') as cssFile: @@ -6145,32 +6158,33 @@ def htmlSearch(translate: {}, if os.path.isfile(themeSearchBannerFilename): copyfile(themeSearchBannerFilename, searchBannerFilename) if os.path.isfile(searchBannerFilename): - followStr += '
' + \ + followStr += '
\n
\n' + \ '







' + \ - '







\n' + '







\n
\n
\n' # show the search box - followStr += '\n' followStr += htmlFooter() return followStr @@ -6336,38 +6350,38 @@ def htmlProfileAfterSearch(recentPostsCache: {}, maxRecentPosts: int, avatarDescription = avatarDescription.replace('

', '') if '<' in avatarDescription: avatarDescription = removeHtml(avatarDescription) - profileStr = '
' - profileStr += '
' + profileStr = '
\n' + profileStr += '
\n' if avatarUrl: profileStr += \ ' ' + avatarDescription + '' - profileStr += '

' + displayName + '

' + avatarDescription + '" class="title">\n' + profileStr += '

' + displayName + '

\n' profileStr += '

@' + searchNickname + '@' + \ - searchDomainFull + '

' - profileStr += '

' + profileDescriptionShort + '

' - profileStr += '
' - profileStr += '
' + searchDomainFull + '

\n' + profileStr += '

' + profileDescriptionShort + '

\n' + profileStr += '
\n' + profileStr += '
\n' profileStr += '
\n' profileStr += '
' - profileStr += '
' + backUrl + '/followconfirm">\n' + profileStr += '
\n' profileStr += \ ' ' + personUrl + '">\n' profileStr += \ ' ' + translate['Follow'] + '\n' profileStr += \ ' ' + translate['View'] + '\n' profileStr += \ ' ' - profileStr += '
' - profileStr += ' ' - profileStr += '
' + translate['Go Back'] + '\n' + profileStr += '
\n' + profileStr += ' \n' + profileStr += '
\n' iconsDir = getIconsDir(baseDir) i = 0