diff --git a/webinterface.py b/webinterface.py index 321a7a17b..6dd4a39c3 100644 --- a/webinterface.py +++ b/webinterface.py @@ -266,28 +266,26 @@ def htmlSearchSharedItems(translate: {}, \ sharedItemsForm+='

' if not resultsExist and currPage>1: # previous page link, needs to be a POST - sharedItemsForm+= \ - '
' \ - ' ' \ - '
' \ - '
' \ - ' '+translate['Page up']+'' \ - '
' \ - '
' - resultsExist=True + sharedItemsForm+='
' + sharedItemsForm+=' ' + sharedItemsForm+='
' + sharedItemsForm+='
' + sharedItemsForm+=' '+translate['Page up']+'' + sharedItemsForm+='
' + sharedItemsForm+='
' + resultsExist=True ctr+=1 if ctr>=resultsPerPage: currPage+=1 if currPage>pageNumber: # next page link, needs to be a POST - sharedItemsForm+= \ - '
' \ - ' ' \ - '
' \ - '
' \ - ' '+translate['Page down']+'' \ - '
' \ - '
' + sharedItemsForm+='
' + sharedItemsForm+=' ' + sharedItemsForm+='
' + sharedItemsForm+='
' + sharedItemsForm+=' '+translate['Page down']+'' + sharedItemsForm+='
' + sharedItemsForm+='
' break ctr=0 if not resultsExist: @@ -311,24 +309,22 @@ def htmlModerationInfo(translate: {},baseDir: str) -> str: if os.path.isfile(suspendedFilename): with open(suspendedFilename, "r") as f: suspendedStr = f.read() - infoForm+= \ - '
' \ - '
'+translate['Suspended accounts']+'' \ - '
'+translate['These are currently suspended']+ \ - ' ' \ - '
' + infoForm+='
' + infoForm+='
'+translate['Suspended accounts']+'' + infoForm+='
'+translate['These are currently suspended'] + infoForm+=' ' + infoForm+='
' infoShown=True blockingFilename=baseDir+'/accounts/blocking.txt' if os.path.isfile(blockingFilename): with open(blockingFilename, "r") as f: blockedStr = f.read() - infoForm+= \ - '
' \ - '
'+translate['Blocked accounts and hashtags']+'' \ - '
'+translate['These are globally blocked for all accounts on this instance']+ \ - ' ' \ - '
' + infoForm+='
' + infoForm+='
'+translate['Blocked accounts and hashtags']+'' + infoForm+='
'+translate['These are globally blocked for all accounts on this instance'] + infoForm+=' ' + infoForm+='
' infoShown=True if not infoShown: infoForm+='

'+translate['Any blocks or suspensions made by moderators will be shown here.']+'

' @@ -597,66 +593,65 @@ def htmlEditProfile(translate: {},baseDir: str,path: str,domain: str,port: int) if os.path.isfile(moderatorsFile): with open(moderatorsFile, "r") as f: moderators = f.read() - moderatorsStr= \ - '
' \ - ' '+translate['Moderators']+'
' \ - ' '+translate['A list of moderator nicknames. One per line.']+ \ - ' ' \ - '
' + moderatorsStr='
' + moderatorsStr+=' '+translate['Moderators']+'
' + moderatorsStr+=' '+translate['A list of moderator nicknames. One per line.'] + moderatorsStr+=' ' + moderatorsStr+='
' editProfileForm=htmlHeader(cssFilename,editProfileCSS) - editProfileForm+= \ - '
' \ - '
' \ - '

'+translate['Profile for']+' '+nickname+'@'+domainFull+'

' \ - '
' \ - ' ' \ - ' ' \ - '
'+ \ - '
' \ - ' ' \ - ' '+ \ - translate['Donations link']+'
'+ \ - ' ' \ - '
' \ - '
' \ - ' '+translate['The files attached below should be no larger than 10MB in total uploaded at once.']+'
' \ - ' '+translate['Avatar image']+ \ - ' ' \ - '
'+translate['Background image']+ \ - ' ' \ - '
'+translate['Timeline banner image']+ \ - ' ' \ - '
' \ - '
' \ - ' '+translate['Approve follower requests']+'
' \ - ' '+translate['This is a bot account']+'
' \ - ' '+translate['This is a group account']+'
' \ - ' '+translate['Only people I follow can send me DMs']+'
' \ - '
'+translate['Filtered words']+'' \ - '
'+translate['One per line']+ \ - ' ' \ - '
'+translate['Blocked accounts']+'' \ - '
'+translate['Blocked accounts, one per line, in the form nickname@domain or *@blockeddomain']+ \ - ' ' \ - '
'+translate['Federation list']+'' \ - '
'+translate['Federate only with a defined set of instances. One domain name per line.']+ \ - ' ' \ - '
' \ - '
' \ - ' '+translate['Skills']+'
' \ - ' '+translate['If you want to participate within organizations then you can indicate some skills that you have and approximate proficiency levels. This helps organizers to construct teams with an appropriate combination of skills.']+ \ - skillsStr+moderatorsStr+ \ - '
' \ - '
' \ - ' '+translate['Danger Zone']+'
' \ - ' '+translate['Deactivate this account']+'
' \ - '
' \ - '
' \ - '
' + editProfileForm+= + editProfileForm+='
' + editProfileForm+='
' + editProfileForm+='

'+translate['Profile for']+' '+nickname+'@'+domainFull+'

' + editProfileForm+='
' + editProfileForm+=' ' + editProfileForm+=' ' + editProfileForm+='
' + editProfileForm+='
' + editProfileForm+=' ' + editProfileForm+=' ' + editProfileForm+=translate['Donations link']+'
' + editProfileForm+=' ' + editProfileForm+='
' + editProfileForm+='
' + editProfileForm+=' '+translate['The files attached below should be no larger than 10MB in total uploaded at once.']+'
' + editProfileForm+=' '+translate['Avatar image'] + editProfileForm+=' '+translate['Approve follower requests']+'
' + editProfileForm+=' '+translate['This is a bot account']+'
' + editProfileForm+=' '+translate['This is a group account']+'
' + editProfileForm+=' '+translate['Only people I follow can send me DMs']+'
' + editProfileForm+='
'+translate['Filtered words']+'' + editProfileForm+='
'+translate['One per line'] + editProfileForm+=' ' + editProfileForm+='
'+translate['Blocked accounts']+'' + editProfileForm+='
'+translate['Blocked accounts, one per line, in the form nickname@domain or *@blockeddomain'] + editProfileForm+=' ' + editProfileForm+='
'+translate['Federation list']+'' + editProfileForm+='
'+translate['Federate only with a defined set of instances. One domain name per line.'] + editProfileForm+=' ' + editProfileForm+='
' + editProfileForm+='
' + editProfileForm+=' '+translate['Skills']+'
' + editProfileForm+=' '+translate['If you want to participate within organizations then you can indicate some skills that you have and approximate proficiency levels. This helps organizers to construct teams with an appropriate combination of skills.'] + editProfileForm+=skillsStr+moderatorsStr + editProfileForm+='
' + editProfileForm+='
' + editProfileForm+=' '+translate['Danger Zone']+'
' + editProfileForm+=' '+translate['Deactivate this account']+'
' + editProfileForm+='
' + editProfileForm+='
' + editProfileForm+='
' editProfileForm+=htmlFooter() return editProfileForm @@ -732,22 +727,21 @@ def htmlLogin(translate: {},baseDir: str,autocomplete=True) -> str: autocompleteStr='autocomplete="off" value=""' loginForm=htmlHeader(cssFilename,loginCSS) - loginForm+= \ - '
' \ - '
' \ - ' login image'+ \ - loginText+TOSstr+ \ - '
' \ - '' \ - '
' \ - ' ' \ - ' ' \ - '' \ - ' ' \ - ' '+ \ - registerButtonStr+loginButtonStr+ \ - '
' \ - '
' + loginForm+='
' + loginForm+='
' + loginForm+=' login image' + loginForm+=loginText+TOSstr + loginForm+='
' + loginForm+='' + loginForm+='
' + loginForm+=' ' + loginForm+=' ' + loginForm+='' + loginForm+=' ' + loginForm+=' ' + loginForm+=registerButtonStr+loginButtonStr + loginForm+='
' + loginForm+='
' loginForm+='' loginForm+=htmlFooter() return loginForm @@ -920,25 +914,23 @@ def htmlNewPost(translate: {},baseDir: str, \ placeholderSubject=translate['Name of the shared item']+'...' placeholderMessage=translate['Description of the item being shared']+'...' endpoint='newshare' - extraFields= \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - '
' \ - '' + extraFields='
' + extraFields+=' ' + extraFields+=' ' + extraFields+=' ' + extraFields+='
' + extraFields+='' dateAndLocation='' if endpoint!='newshare' and endpoint!='newreport': - dateAndLocation= \ - '
' \ - '

' \ - '' \ - '' \ - '

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

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

' + dateAndLocation+='' + dateAndLocation+='
' newPostForm=htmlHeader(cssFilename,newPostCSS) @@ -988,43 +980,41 @@ def htmlNewPost(translate: {},baseDir: str, \ dropDownContent='' if not reportUrl: - dropDownContent= \ - ' ' + dropDownContent+=' ' else: mentionsStr='Re: '+reportUrl+'\n\n'+mentionsStr - newPostForm+= \ - '
' \ - '
' \ - ' ' \ - '
' \ - '
' \ - ' '+scopeDescription+''+ \ - dropDownContent+ \ - '
' \ - ' ' \ - ' ' \ - ' '+translate['Search for emoji']+''+ \ - '
'+ \ - replyStr+ \ - ' ' \ - '' \ - ' '+ \ - extraFields+dateAndLocation+ \ - '
' \ - ' ' \ - ' ' \ - '
' \ - '
' \ - '
' + newPostForm+='
' + newPostForm+='
' + newPostForm+=' ' + newPostForm+='
' + newPostForm+='
' + newPostForm+=' '+scopeDescription+'' + newPostForm+=dropDownContent + newPostForm+='
' + newPostForm+=' ' + newPostForm+=' ' + newPostForm+=' '+translate['Search for emoji']+'' + newPostForm+='
' + newPostForm+=replyStr + newPostForm+=' ' + newPostForm+='' + newPostForm+=' ' + newPostForm+=extraFields+dateAndLocation + newPostForm+='
' + newPostForm+=' ' + newPostForm+=' ' @@ -1042,28 +1032,25 @@ def htmlHeader(cssFilename: str,css=None,refreshSec=0,lang='en') -> str: if not css: if '/' in cssFilename: cssFilename=cssFilename.split('/')[-1] - htmlStr= \ - '\n' \ - '\n'+ \ - meta+ \ - ' \n' \ - ' \n' + htmlStr='\n' + htmlStr+='\n' + htmlStr+=meta + htmlStr+=' \n' + htmlStr+=' \n' else: - htmlStr= \ - '\n' \ - '\n'+ \ - meta+ \ - ' \n' \ - ' \n' + htmlStr='\n' + htmlStr+='\n' + htmlStr+=meta + htmlStr+=' \n' + htmlStr+=' \n' return htmlStr def htmlFooter() -> str: - htmlStr= \ - ' \n' \ - '\n' + htmlStr=' \n' + htmlStr+='\n' return htmlStr def htmlProfilePosts(translate: {}, \ @@ -1337,12 +1324,11 @@ def htmlProfile(translate: {},projectVersion: str, \ donateSection='' donateUrl=getDonationUrl(profileJson) if donateUrl: - donateSection= \ - '
\n' \ - '
\n' \ - ' \n' \ - '
\n' \ - '
\n' + donateSection='
\n' + donateSection+='
\n' + donateSection+=' \n' + donateSection+='
\n' + donateSection+='
\n' if not authorized: loginButton='
' @@ -1397,29 +1383,28 @@ def htmlProfile(translate: {},projectVersion: str, \ avatarDescription='' if profileJson.get('summary'): avatarDescription=profileJson['summary'].replace('
','\n').replace('

','').replace('

','') - profileHeaderStr= \ - '
' \ - '
'+ \ - ' '+avatarDescription+'' \ - '

'+displayName+'

' \ - '

@'+nickname+'@'+domainFull+'

' \ - '

'+profileDescriptionShort+'

'+ \ - loginButton+ \ - '
' \ - '
' - profileStr= \ - linkToTimelineStart + profileHeaderStr + linkToTimelineEnd + donateSection + \ - '
\n' \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - ' '+ \ - editProfileStr+logoutStr+ \ - '
' \ - '
' + profileHeaderStr='
' + profileHeaderStr+='
' + profileHeaderStr+=' '+avatarDescription+'' + profileHeaderStr+='

'+displayName+'

' + profileHeaderStr+='

@'+nickname+'@'+domainFull+'

' + profileHeaderStr+='

'+profileDescriptionShort+'

' + profileHeaderStr+=loginButton + profileHeaderStr+='
' + profileHeaderStr+='
' + + profileStr=linkToTimelineStart + profileHeaderStr + linkToTimelineEnd + donateSection + profileStr+='
\n' + profileStr+='
' + profileStr+=' ' + profileStr+=' ' + profileStr+=' ' + profileStr+=' ' + profileStr+=' ' + profileStr+=' ' + profileStr+=editProfileStr+logoutStr + profileStr+='
' + profileStr+='
' profileStr+=followApprovalsSection @@ -1504,55 +1489,52 @@ def individualFollowAsHtml(translate: {}, \ buttonsStr+='' #buttonsStr+='' - return \ - '
\n' \ - '' \ - '

 \n'+ \ - titleStr+''+buttonsStr+'

' \ - '
\n' + resultStr='
\n' + resultStr+='' + resultStr+='

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

' + resultStr+='
\n' + return resultStr def clickToDropDownScript() -> str: """Function run onclick to create a dropdown """ - script= \ - 'function dropdown() {\n' \ - ' document.getElementById("myDropdown").classList.toggle("show");\n' \ - '}\n' + script='function dropdown() {\n' + script+=' document.getElementById("myDropdown").classList.toggle("show");\n' + script+='}\n' return script def cursorToEndOfMessageScript() -> str: """Moves the cursor to the end of the text in a textarea This avoids the cursor being in the wrong position when replying """ - script = \ - 'function focusOnMessage() {\n' \ - " var replyTextArea = document.getElementById('message');\n" \ - ' val = replyTextArea.value;\n' \ - ' if ((val.length>0) && (val.charAt(val.length-1) != " ")) {\n' \ - ' val += " ";\n' \ - ' }\n' \ - ' replyTextArea.focus();\n' \ - ' replyTextArea.value="";\n' \ - ' replyTextArea.value=val;\n' \ - '}\n' \ - "var replyTextArea = document.getElementById('message')\n" \ - 'replyTextArea.onFocus = function() {\n' \ - ' focusOnMessage();' \ - '}\n' + script='function focusOnMessage() {\n' + script+=" var replyTextArea = document.getElementById('message');\n" + script+=' val = replyTextArea.value;\n' + script+=' if ((val.length>0) && (val.charAt(val.length-1) != " ")) {\n' + script+=' val += " ";\n' + script+=' }\n' + script+=' replyTextArea.focus();\n' + script+=' replyTextArea.value="";\n' + script+=' replyTextArea.value=val;\n' + script+='}\n' + script+="var replyTextArea = document.getElementById('message')\n" + script+='replyTextArea.onFocus = function() {\n' + script+=' focusOnMessage();' + script+='}\n' return script def contentWarningScript() -> str: """Returns a script used for content warnings """ - script= \ - 'function showContentWarning(postID) {\n' \ - ' var x = document.getElementById(postID);\n' \ - ' if (x.style.display !== "block") {\n' \ - ' x.style.display = "block";\n' \ - ' } else {\n' \ - ' x.style.display = "none";\n' \ - ' }\n' \ - '}\n' + script='function showContentWarning(postID) {\n' + script+=' var x = document.getElementById(postID);\n' + script+=' if (x.style.display !== "block") {\n' + script+=' x.style.display = "block";\n' + script+=' } else {\n' + script+=' x.style.display = "none";\n' + script+=' }\n' + script+='}\n' return script def addEmbeddedAudio(translate: {},content: str) -> str: @@ -2002,12 +1984,11 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ # show avatar of person replied to replyAvatarUrl=getPersonAvatarUrl(baseDir,replyActor,personCache) if replyAvatarUrl: - replyAvatarImageInPost= \ - '
' \ - '' \ - '
' + replyAvatarImageInPost='
' + replyAvatarImageInPost+='' + replyAvatarImageInPost+='
' else: titleStr+=' @'+replyNickname+'@'+replyDomain+'' else: @@ -2039,14 +2020,13 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ if attachmentCtr>0: attachmentStr+='
' if boxName=='tlmedia': - galleryStr+= \ - '\n' - attachmentStr+= \ - '' \ - ''+imageDescription+'\n' + galleryStr+='\n' + + attachmentStr+='' + attachmentStr+=''+imageDescription+'\n' attachmentCtr+=1 elif mediaType=='video/mp4' or \ mediaType=='video/webm' or \ @@ -2060,19 +2040,18 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ if attachmentCtr>0: attachmentStr+='
' if boxName=='tlmedia': - galleryStr+= \ - '\n' - attachmentStr+= \ - '
' + galleryStr+='\n' + + attachmentStr+='
' attachmentCtr+=1 elif mediaType=='audio/mpeg' or \ mediaType=='audio/ogg': @@ -2083,19 +2062,18 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ if attachmentCtr>0: attachmentStr+='
' if boxName=='tlmedia': - galleryStr+= \ - '\n' - attachmentStr+= \ - '
' + galleryStr+='\n' + + attachmentStr+='
' attachmentCtr+=1 attachmentStr+='
' @@ -2128,18 +2106,16 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ displayName,False) titleStr=displayName+' '+titleStr - avatarImageInPost= \ - '
' \ - ' ' \ - '  ' \ - '
' + avatarImageInPost='
' + avatarImageInPost+=' ' + avatarImageInPost+='  ' + avatarImageInPost+='
' if showAvatarOptions and fullDomain+'/users/'+nickname not in postActor: - avatarImageInPost= \ - '
' \ - ' ' \ - ' ' \ - '
' + avatarImageInPost='
' + avatarImageInPost+=' ' + avatarImageInPost+=' ' + avatarImageInPost+='
' publishedStr=postJsonObject['object']['published'] if '.' not in publishedStr: @@ -2167,9 +2143,8 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ announceIcon='repeat.png' announceLink='unrepeat' announceTitle=translate['Undo the repeat'] - announceStr= \ - '' \ - '' + announceStr='' + announceStr+='' likeStr='' if not isModerationPost: @@ -2181,18 +2156,16 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ if likedByPerson(postJsonObject,nickname,fullDomain): likeLink='unlike' likeTitle=translate['Undo the like'] - likeStr= \ - '' \ - '' + likeStr='' + likeStr+='' deleteStr='' if allowDeletion or \ ('/'+fullDomain+'/' in postActor and \ postJsonObject['object']['id'].startswith(postActor)): if '/users/'+nickname+'/' in postJsonObject['object']['id']: - deleteStr= \ - '' \ - '' + deleteStr='' + deleteStr+='' # change the background color for DMs in inbox timeline if showDMicon: @@ -2260,12 +2233,11 @@ def individualPostAsHtml(iconsDir: str,translate: {}, \ postHtml='' if boxName!='tlmedia': - postHtml= \ - '
\n'+ \ - avatarImageInPost+ \ - '

'+titleStr+replyAvatarImageInPost+'

'+ \ - contentStr+footerStr+ \ - '
\n' + postHtml='
\n' + postHtml+=avatarImageInPost + postHtml+='

'+titleStr+replyAvatarImageInPost+'

' + postHtml+=contentStr+footerStr + postHtml+='
\n' else: postHtml=galleryStr @@ -2415,36 +2387,34 @@ def htmlTimeline(translate: {},pageNumber: int, \ newPostButtonStr=''+translate['Create a new DM']+'' # banner and row of buttons - tlStr+= \ - '' \ - '
' \ - '
' \ - '
\n'+ \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - ' '+ \ - sharesButtonStr+moderationButtonStr+newPostButtonStr+ \ - ' '+translate['Search and follow']+''+ \ - ' '+translate['Calendar']+''+ \ - ' '+translate['Refresh']+''+ \ - followApprovals+ \ - '
' + tlStr+='' + tlStr+='
' + tlStr+='
' + tlStr+='
\n' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+=sharesButtonStr+moderationButtonStr+newPostButtonStr + tlStr+=' '+translate['Search and follow']+'' + tlStr+=' '+translate['Calendar']+'' + tlStr+=' '+translate['Refresh']+'' + tlStr+=followApprovals + tlStr+='
' # second row of buttons for moderator actions if moderator and boxName=='moderation': - tlStr+= \ - '' \ - '
\n'+ \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - '
' + tlStr+='
' + tlStr+='
\n' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+=' ' + tlStr+='
' if boxName=='tlshares': maxSharesPerAccount=itemsPerPage @@ -2702,13 +2672,12 @@ def htmlRemoveSharedItem(translate: {},baseDir: str,actor: str,shareName: str) - if sharedItemImageUrl: sharesStr+=' ' sharesStr+='

'+translate['Remove']+' '+sharedItemDisplayName+' ?

' - sharesStr+= \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - '
' + sharesStr+='
' + sharesStr+=' ' + sharesStr+=' ' + sharesStr+=' ' + sharesStr+=' ' + sharesStr+='
' sharesStr+=' ' sharesStr+='
' sharesStr+='' @@ -2758,13 +2727,12 @@ def htmlDeletePost(translate,pageNumber: int, \ False,False,False,False,False) deletePostStr+='
' deletePostStr+='

'+translate['Delete this post?']+'

' - deletePostStr+= \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - '
' + deletePostStr+='
' + deletePostStr+=' ' + deletePostStr+=' ' + deletePostStr+=' ' + deletePostStr+=' ' + deletePostStr+='
' deletePostStr+='
' deletePostStr+=htmlFooter() return deletePostStr @@ -2793,12 +2761,11 @@ def htmlFollowConfirm(translate: {},baseDir: str, \ followStr+=' ' followStr+=' ' followStr+='

'+translate['Follow']+' '+getNicknameFromActor(followActor)+'@'+followDomain+' ?

' - followStr+= \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - '
' + followStr+='
' + followStr+=' ' + followStr+=' ' + followStr+=' ' + followStr+='
' followStr+='' followStr+='' followStr+='' @@ -2829,12 +2796,11 @@ def htmlUnfollowConfirm(translate: {},baseDir: str, \ followStr+=' ' followStr+=' ' followStr+='

'+translate['Stop following']+' '+getNicknameFromActor(followActor)+'@'+followDomain+' ?

' - followStr+= \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - '
' + followStr+='
' + followStr+=' ' + followStr+=' ' + followStr+=' ' + followStr+='
' followStr+='' followStr+='' followStr+='' @@ -2904,20 +2870,19 @@ def htmlPersonOptions(translate: {},baseDir: str, \ optionsStr+=' ' optionsStr+=' ' optionsStr+='

'+translate['Options for']+' @'+getNicknameFromActor(optionsActor)+'@'+optionsDomain+'

' - optionsStr+= \ - '
' \ - ' ' \ - ' ' \ - ' '+ \ - optionsLinkStr+ \ - ' '+ \ - donateStr+ \ - ' ' \ - ' ' \ - ' '+ \ - ' ' \ - ' ' \ - '
' + optionsStr+='
' + optionsStr+=' ' + optionsStr+=' ' + optionsStr+=' ' + optionsStr+=optionsLinkStr + optionsStr+=' ' + optionsStr+=donateStr + optionsStr+=' ' + optionsStr+=' ' + optionsStr+=' ' + optionsStr+=' ' + optionsStr+=' ' + optionsStr+='
' optionsStr+='' optionsStr+='' optionsStr+='' @@ -2945,12 +2910,11 @@ def htmlPersonOptions(translate: {},baseDir: str, \ # blockStr+=' ' # blockStr+=' ' # blockStr+='

'+translate['Block']+' '+getNicknameFromActor(blockActor)+'@'+blockDomain+' ?

' -# blockStr+= \ -# '
' \ -# ' ' \ -# ' ' \ -# ' ' \ -# '
' +# blockStr+='
' +# blockStr+=' ' +# blockStr+=' ' +# blockStr+=' ' +# blockStr+='
' # blockStr+='' # blockStr+='' # blockStr+='' @@ -2981,12 +2945,11 @@ def htmlUnblockConfirm(translate: {},baseDir: str, \ blockStr+=' ' blockStr+=' ' blockStr+='

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

' - blockStr+= \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - '
' + blockStr+='
' + blockStr+=' ' + blockStr+=' ' + blockStr+=' ' + blockStr+='
' blockStr+='' blockStr+='' blockStr+='' @@ -3020,12 +2983,11 @@ def htmlSearchEmojiTextEntry(translate: {}, \ emojiStr+='
' emojiStr+='
' emojiStr+='

'+translate['Enter an emoji name to search for']+'

' - emojiStr+= \ - '
' \ - ' ' \ - '
' \ - ' ' \ - '
' + emojiStr+='
' + emojiStr+=' ' + emojiStr+='
' + emojiStr+=' ' + emojiStr+='
' emojiStr+='
' emojiStr+='
' emojiStr+='' @@ -3319,12 +3281,11 @@ def htmlSearch(translate: {}, \ followStr+='
' followStr+='
' followStr+='

'+translate['Enter an address, shared item, #hashtag, *skill or :emoji: to search for']+'

' - followStr+= \ - '
' \ - ' ' \ - '
' \ - ' ' \ - '
' + followStr+='
' + followStr+=' ' + followStr+='
' + followStr+=' ' + followStr+='
' followStr+='
' followStr+='
' followStr+='' @@ -3452,25 +3413,24 @@ def htmlProfileAfterSearch(translate: {}, \ avatarDescription='' if profileJson.get('summary'): avatarDescription=profileJson['summary'].replace('
','\n').replace('

','').replace('

','') - profileStr= \ - '
' \ - '
' \ - ' '+avatarDescription+'' \ - '

'+displayName+'

' \ - '

@'+searchNickname+'@'+searchDomainFull+'

' \ - '

'+profileDescriptionShort+'

'+ \ - '
' \ - '
'+ \ - '
\n' \ - '
' \ - '
' \ - ' ' \ - ' ' \ - ' ' \ - ' ' \ - '
' \ - '
' \ - '
' + profileStr='
' + profileStr+='
' + profileStr+=' '+avatarDescription+'' + profileStr+='

'+displayName+'

' + profileStr+='

@'+searchNickname+'@'+searchDomainFull+'

' + profileStr+='

'+profileDescriptionShort+'

' + profileStr+='
' + profileStr+='
' + profileStr+='
\n' + profileStr+='
' + profileStr+='
' + profileStr+=' ' + profileStr+=' ' + profileStr+=' ' + profileStr+=' ' + profileStr+='
' + profileStr+='
' + profileStr+='
' profileStr+=''