Tweak nav button html generation

alt-html-css
Admin 2020-11-24 14:08:21 +00:00
parent b12cf702aa
commit 13b57ff16a
1 changed files with 339 additions and 255 deletions

View File

@ -39,288 +39,372 @@ def headerButtonsTimeline(defaultTimeline: str,
baseDir: str, baseDir: str,
nickname: str, domain: str, nickname: str, domain: str,
timelineStartTime, timelineStartTime,
newCalendarEvent: bool, iconsAsButtons: bool,
calendarPath: str, userPages: []) -> str:
calendarImage: str,
followApprovals: str,
iconsAsButtons: bool) -> str:
"""Returns the header at the top of the timeline, containing """Returns the header at the top of the timeline, containing
buttons for inbox, outbox, search, calendar, etc buttons for inbox, outbox, search, calendar, etc
""" """
# start of the button header with inbox, outbox, etc # start of the button header with inbox, outbox, etc
tlStr = '<div class="containerHeader"><nav>\n' # TODO: [rename] containerHeader -> menu (or similar)
# first button
if defaultTimeline == 'tlmedia':
tlStr += \
'<a href="' + usersPath + \
'/tlmedia"><button class="' + \
mediaButton + '"><span>' + translate['Media'] + \
'</span></button></a>'
elif defaultTimeline == 'tlblogs':
tlStr += \
'<a href="' + usersPath + \
'/tlblogs"><button class="' + \
blogsButton + '"><span>' + translate['Blogs'] + \
'</span></button></a>'
elif defaultTimeline == 'tlfeatures':
tlStr += \
'<a href="' + usersPath + \
'/tlfeatures"><button class="' + \
featuresButton + '"><span>' + translate['Features'] + \
'</span></button></a>'
else:
tlStr += \
'<a href="' + usersPath + \
'/inbox"><button class="' + \
inboxButton + '"><span>' + \
translate['Inbox'] + '</span></button></a>'
# if this is a news instance and we are viewing the news timeline tlStr = '\t<div class="containerHeader">\n'
featuresHeader = False
if defaultTimeline == 'tlfeatures' and boxName == 'tlfeatures':
featuresHeader = True
if not featuresHeader:
tlStr += \
'<a href="' + usersPath + \
'/dm"><button class="' + dmButton + \
'"><span>' + htmlHighlightLabel(translate['DM'], newDM) + \
'</span></button></a>'
repliesIndexFilename = \ # TODO: Group _all_ items that are hidden in 'minimal' mode ?
# - Are there others elsewhere in the code ?
# All menu items default to text buttons
# Add class "icon-button" to overwrite default behaviour
# NOTE: Currently handled further down in loops over navButtonList and navIconList
# Menu buttons are split into two sections
# - Navigation buttons : Informational pages, e.g. Inbox
# - Action buttons : More clear action, e.g. Search, Create Post
# default appearance text; use CSS class(es) to re-style
# A list of buttons to be rendered as html,
# each item being a tuple containing
# - ref name
# - dictionary of unique config
# Each dict has:
# - pageRef : the url snippet
# - translationText : text to be displayed
# - highlightLabel : boolean to determine highlight
# - isIcon : boolean to trigger specific CSS class addition(s) for icon buttons
# - class : string of class(es) to append
# - iconClass : string of class(es) to append, only regarding icons
# Buttons should be added in the order you wish them to appear in the menu
navButtonList = []
navIconList = []
# Use this to selectively append to one or other of the above lists
activeButtonList = navButtonList
# Too many buttons - some visibility can be toggled
# TODO: Show/Hide menu buttons should not require page reload!
# Implement checkbox method
# Requires grouping the buttons that are shown/hidden ?
# TODO: The 'minimal' attribute could be done using CSS class ?
# Minimal View only shows:
# - Inbox
# - Outbox
# - DM
# - Replies
# - News # TODO: Should this be in minimal view? 'Media' and 'Blogs' are not ...
# NOTE: "Action" buttons (icons in default Epicyon) are always visible
activeButtonList.append(('inbox',
{'pageRef': '/inbox',
'translateText': 'Inbox'}
))
activeButtonList.append(('outbox',
{'pageRef': '/outbox',
'translateText': 'Outbox'}
))
activeButtonList.append(('dm',
{'pageRef': '/dm',
'translateText': 'DM',
'highlightLabel': newDM}
))
activeButtonList.append(('tlreplies',
{'pageRef': '/tlreplies',
'translateText': 'Replies',
'highlightLabel': newReply}
))
if (defaultTimeline == 'tlnews' and boxName in userPages) \
or (not defaultTimeline == 'tlnews' and not minimal):
activeButtonList.append(('tlnews',
{'pageRef': '/tlnews',
'translateText': 'News'}
))
# The following translationText should be 'Article' for News instances
activeButtonList.append(('tlblogs',
{'pageRef': '/tlblogs',
'translateText': 'Blogs'}
))
activeButtonList.append(('tlmedia',
{'pageRef': '/tlmedia',
'translateText': 'Media'}
))
activeButtonList.append(('tlshares',
{'pageRef': '/tlshares',
'translateText': 'Shares',
'highlightLabel': newShare}
))
activeButtonList.append(('tlbookmarks',
{'pageRef': '/tlbookmarks',
'translateText': 'Bookmarks'}
))
activeButtonList.append(('tlevents',
{'pageRef': '/tlevents',
'translateText': 'Events'}
))
if moderator:
activeButtonList.append(('moderation',
{'pageRef': '/moderation',
'translateText': 'Mod',
'highlightLabel': newReport}
))
# Single out the "instance-type" button, and move to front of list
# NOTE: Current instance types are: 'tlblogs', 'tlmedia', 'tlnews'
for i, (name, config) in enumerate(activeButtonList):
if name == defaultTimeline:
tmp = activeButtonList.pop(i)
activeButtonList.insert(0, tmp)
break
# start of headericons list
# Override iconsAsButtons setting for News instance
if defaultTimeline == 'tlnews':
iconsAsButtons = True
# Only append to iconList if necessary
if not iconsAsButtons:
activeButtonList = navIconList
# show an icon for new follow approvals
followApprovals = False
followRequestsFilename = \
baseDir + '/accounts/' + \ baseDir + '/accounts/' + \
nickname + '@' + domain + '/tlreplies.index' nickname + '@' + domain + '/followrequests.txt'
if os.path.isfile(repliesIndexFilename): if os.path.isfile(followRequestsFilename):
tlStr += \ with open(followRequestsFilename, 'r') as f:
'<a href="' + usersPath + '/tlreplies"><button class="' + \ for line in f:
repliesButton + '"><span>' + \ if len(line) > 0:
htmlHighlightLabel(translate['Replies'], newReply) + \ # show follow approvals icon
'</span></button></a>' followApprovals = True
break
# typically the media button # NOTE: Certain buttons only appear when relevant
if defaultTimeline != 'tlmedia':
if not minimal and not featuresHeader:
tlStr += \
'<a href="' + usersPath + \
'/tlmedia"><button class="' + \
mediaButton + '"><span>' + translate['Media'] + \
'</span></button></a>'
else:
if not minimal:
tlStr += \
'<a href="' + usersPath + \
'/inbox"><button class="' + \
inboxButton+'"><span>' + translate['Inbox'] + \
'</span></button></a>'
if not featuresHeader: # TODO: Determine if approvals (currently appended at end of activeButtonList)
# typically the blogs button # and events should be in a separate list;
# but may change if this is a blogging oriented instance # e.g. notificationButtonList
if defaultTimeline != 'tlblogs': # Having its' own <div> for instance would allow more versatile styling
if not minimal: if followApprovals:
titleStr = translate['Blogs'] activeButtonList.append(('followers',
if defaultTimeline == 'tlfeatures': {'pageRef': '/followers',
titleStr = translate['Article'] 'translateText': 'Approve follow requests',
tlStr += \ 'iconClass': 'icon-newfollow'}
'<a href="' + usersPath + \ ))
'/tlblogs"><button class="' + \
blogsButton + '"><span>' + titleStr + \
'</span></button></a>'
else:
if not minimal:
tlStr += \
'<a href="' + usersPath + \
'/inbox"><button class="' + \
inboxButton + '"><span>' + translate['Inbox'] + \
'</span></button></a>'
# typically the news button # Only show todays events buttons on the first inbox page
# but may change if this is a news oriented instance
if defaultTimeline == 'tlfeatures':
if not featuresHeader:
tlStr += \
'<a href="' + usersPath + \
'/inbox"><button class="' + \
inboxButton + '"><span>' + translate['Inbox'] + \
'</span></button></a>'
# show todays events buttons on the first inbox page
happeningStr = ''
if boxName == 'inbox' and pageNumber == 1: if boxName == 'inbox' and pageNumber == 1:
if todaysEventsCheck(baseDir, nickname, domain): if todaysEventsCheck(baseDir, nickname, domain):
now = datetime.now() now = datetime.now()
todayRef = '/calendar?year=' + str(now.year) + \
# happening today button '?month=' + str(now.month) + \
if not iconsAsButtons: '?day=' + str(now.day)
happeningStr += \ activeButtonList.append(('today-event',
'<a href="' + usersPath + '/calendar?year=' + \ {'pageRef': todayRef,
str(now.year) + '?month=' + str(now.month) + \ 'translateText': 'Happening Today',
'?day=' + str(now.day) + '">' + \ 'class': 'button-event'}
'<button class="buttonevent">' + \ ))
translate['Happening Today'] + '</button></a>'
else:
happeningStr += \
'<a href="' + usersPath + '/calendar?year=' + \
str(now.year) + '?month=' + str(now.month) + \
'?day=' + str(now.day) + '">' + \
'<button class="button">' + \
translate['Happening Today'] + '</button></a>'
# happening this week button
if thisWeeksEventsCheck(baseDir, nickname, domain): if thisWeeksEventsCheck(baseDir, nickname, domain):
if not iconsAsButtons: activeButtonList.append(('week-event',
happeningStr += \ {'pageRef': '/calendar',
'<a href="' + usersPath + \ 'translateText': 'Happening Today',
'/calendar"><button class="buttonevent">' + \ 'class': 'button-event'}
translate['Happening This Week'] + '</button></a>' ))
else:
happeningStr += \
'<a href="' + usersPath + \
'/calendar"><button class="button">' + \
translate['Happening This Week'] + '</button></a>'
else:
# happening this week button
if thisWeeksEventsCheck(baseDir, nickname, domain):
if not iconsAsButtons:
happeningStr += \
'<a href="' + usersPath + \
'/calendar"><button class="buttonevent">' + \
translate['Happening This Week'] + '</button></a>'
else:
happeningStr += \
'<a href="' + usersPath + \
'/calendar"><button class="button">' + \
translate['Happening This Week'] + '</button></a>'
if not featuresHeader:
# button for the outbox
tlStr += \
'<a href="' + usersPath + \
'/outbox"><button class="' + \
sentButton + '"><span>' + translate['Outbox'] + \
'</span></button></a>'
# add other buttons # NOTE: CSS used to show or hide these based on screen size
tlStr += \ activeButtonList.append(('newswire',
sharesButtonStr + bookmarksButtonStr + eventsButtonStr + \ {'pageRef': '/newswiremobile',
moderationButtonStr + happeningStr + newPostButtonStr 'translateText': 'Newswire',
'class': 'mobile-only',
'iconClass': 'icon-newswire'}
))
activeButtonList.append(('links',
{'pageRef': '/linksmobile',
'translateText': 'Edit Links',
'class': 'mobile-only',
'iconClass': 'icon-links'}
))
if not featuresHeader: # what screen to go to when a new post is created
if not iconsAsButtons: # The following produces one button/icon for "new post" dependent on current viewed page
# the search icon if boxName == 'dm':
tlStr += \ activeButtonList.append(('newdm',
'<a class="imageAnchor" href="' + usersPath + \ {'pageRef': '/newdm',
'/search"><img loading="lazy" src="/' + \ 'translateText': 'Create a new DM'}
'icons/search.png" title="' + \ ))
translate['Search and follow'] + '" alt="| ' + \ elif boxName == 'tlblogs' or boxName == 'tlnews':
translate['Search and follow'] + \ activeButtonList.append(('newblog',
'" class="timelineicon"/></a>' {'pageRef': '/newblog',
'translateText': 'Create a new post'}
))
elif boxName == 'tlevents':
activeButtonList.append(('newevent',
{'pageRef': '/newevent',
'translateText': 'Create a new event'}
))
else: else:
# the search button if not manuallyApproveFollowers:
tlStr += \ activeButtonList.append(('newpost',
'<a href="' + usersPath + \ {'pageRef': '/newpost',
'/search"><button class="button">' + \ 'translateText': 'Create a new post'}
'<span>' + translate['Search'] + \ ))
'</span></button></a>' else:
activeButtonList.append(('newfollowers',
{'pageRef': '/newfollowers',
'translateText': 'Create a new post'}
))
# 'icon-<type>' is solely used for the CSS to load appropriate icon
activeButtonList[-1][1]['iconClass'] = 'icon-newpost'
activeButtonList.append(('calendar',
{'pageRef': calendarPath,
'translateText': 'Calendar',
'iconClass': 'icon-calendar'}
))
activeButtonList.append(('search',
{'pageRef': '/search',
'translateText': 'Search',
'iconClass': 'icon-search'}
))
activeButtonList.append(('minimal',
{'pageRef': '/minimal',
'translateText': 'Show/Hide Buttons',
'iconClass': 'icon-showhide'}
))
# Generate HTML lists
navButtonStr = ""
if navButtonList:
navButtonStr += '\t\t<div class="navbuttons">\n'
navButtonStr += '\t\t\t<ul class="button-bar">\n'
for name, config in navButtonList:
classStr = 'button'
textStr = ''
if 'class' in config:
classStr += ' ' + config['class']
if 'highlightLabel' in config and config['highlightLabel']:
if name == boxName:
classStr += ' button-selected-highlighted'
else:
classStr += ' button-highlighted'
# TODO: Replace 'config' dereference with 'True' as it always will be by this point ?
textStr = htmlHighlightLabel(translate[config['translateText']], \
config['highlightLabel'])
else:
if name == boxName:
classStr += ' button-selected'
textStr += translate[config['translateText']]
navButtonStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
f'\t\t\t\t\t<li>{textStr}</li>\n'
f'\t\t\t\t</a>\n')
navButtonStr += '\t\t\t</ul>\n\t\t</div>\n'
navIconStr = ""
if navIconList:
navIconStr += '\t\t<div class="actionbuttons">\n'
navIconStr += '\t\t\t<ul class="button-bar">\n'
# TODO: [rename] 'timelineicon' should maybe be more generic, e.g 'icon-button'
# Generate HTML list
for name, config in navIconList:
if iconsAsButtons:
classStr = 'button'
else:
# Currently 'timelineicon' denotes an icon instead of text button
classStr = 'timelineicon'
# NOTE: If iconClass is missing, expect some kind of failed output
# CSS alone is responsible for what image will be displayed, etc
if 'iconClass' in config:
classStr += ' ' + config['iconClass']
if 'class' in config:
classStr += ' ' + config['class']
if 'highlightLabel' in config:
textStr = htmlHighlightLabel(translate[config['translateText']], config['highlightLabel'])
else:
textStr = translate[config['translateText']]
navIconStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
f'\t\t\t\t\t<li>{textStr}</li>\n'
f'\t\t\t\t</a>\n')
navIconStr += '\t\t\t</ul>\n\t\t</div>\n'
# benchmark 5 # benchmark 5
timeDiff = int((time.time() - timelineStartTime) * 1000) timeDiff = int((time.time() - timelineStartTime) * 1000)
if timeDiff > 100: if timeDiff > 100:
print('TIMELINE TIMING ' + boxName + ' 5 = ' + str(timeDiff)) print('TIMELINE TIMING ' + boxName + ' 5 = ' + str(timeDiff))
# the calendar button
if not featuresHeader:
calendarAltText = translate['Calendar']
if newCalendarEvent:
# indicate that the calendar icon is highlighted
calendarAltText = '*' + calendarAltText + '*'
if not iconsAsButtons:
tlStr += \
' <a class="imageAnchor" href="' + \
usersPath + calendarPath + \
'"><img loading="lazy" src="/icons/' + \
calendarImage + '" title="' + translate['Calendar'] + \
'" alt="| ' + calendarAltText + \
'" class="timelineicon"/></a>\n'
else:
tlStr += \
'<a href="' + usersPath + calendarPath + \
'"><button class="button">' + \
'<span>' + translate['Calendar'] + \
'</span></button></a>'
if not featuresHeader: # Compile HTML parts
# the show/hide button, for a simpler header appearance tlStr += navButtonStr + navIconStr
if not iconsAsButtons:
tlStr += \
' <a class="imageAnchor" href="' + \
usersPath + '/minimal' + \
'"><img loading="lazy" src="/icons' + \
'/showhide.png" title="' + translate['Show/Hide Buttons'] + \
'" alt="| ' + translate['Show/Hide Buttons'] + \
'" class="timelineicon"/></a>\n'
else:
tlStr += \
'<a href="' + usersPath + '/minimal' + \
'"><button class="button">' + \
'<span>' + translate['Show/Hide Buttons'] + \
'</span></button></a>'
if featuresHeader: # End header button section
tlStr += \ tlStr += '\t</div>\n'
'<a href="' + usersPath + '/inbox">' + \
'<button class="button">' + \
'<span>' + translate['User'] + '</span></button></a>'
# the newswire button to show right column links
if not iconsAsButtons:
tlStr += \
'<a class="imageAnchorMobile" href="' + \
usersPath + '/newswiremobile">' + \
'<img loading="lazy" src="/icons' + \
'/newswire.png" title="' + translate['News'] + \
'" alt="| ' + translate['News'] + \
'" class="timelineicon"/></a>'
else:
# NOTE: deliberately no \n at end of line
tlStr += \
'<a href="' + \
usersPath + '/newswiremobile' + \
'"><button class="buttonMobile">' + \
'<span>' + translate['Newswire'] + \
'</span></button></a>'
# the links button to show left column links
if not iconsAsButtons:
tlStr += \
'<a class="imageAnchorMobile" href="' + \
usersPath + '/linksmobile">' + \
'<img loading="lazy" src="/icons' + \
'/links.png" title="' + translate['Edit Links'] + \
'" alt="| ' + translate['Edit Links'] + \
'" class="timelineicon"/></a>'
else:
# NOTE: deliberately no \n at end of line
tlStr += \
'<a href="' + \
usersPath + '/linksmobile' + \
'"><button class="buttonMobile">' + \
'<span>' + translate['Links'] + \
'</span></button></a>'
if featuresHeader:
tlStr += \
'<a href="' + usersPath + '/editprofile">' + \
'<button class="buttonDesktop">' + \
'<span>' + translate['Settings'] + '</span></button></a>'
if not featuresHeader:
tlStr += followApprovals
if not iconsAsButtons:
# end of headericons div
tlStr += '</div>'
# end of the button header with inbox, outbox, etc
tlStr += ' </nav></div>\n'
return tlStr return tlStr
def headerNewsTabs(boxName: str,
translate: {},
usersPath: str,
moderator: bool,
baseDir: str,
userPages: []) -> str:
navTabList = []
navTabList.append(('tlnews',
{'pageRef': '/tlnews',
'translateText': 'Features'}
))
navTabList.append(('newswiremobile',
{'pageRef': '/newswiremobile',
'translateText': 'Newswire'}
))
# navTabList.append(('calendar',
# {'pageRef': '/calendar',
# 'translateText': 'Calendar'}
# ))
navTabList.append(('linksmobile',
{'pageRef': '/linksmobile',
'translateText': 'Links'}
))
navTabList.append(('inbox',
{'pageRef': '/inbox',
'translateText': 'User'}
))
navStr = '\t\t<div class="section navtabs">\n'
navStr += '\t\t\t<ul>\n'
for name, config in navTabList:
classStr = ''
if name == boxName:
classStr = 'tab-highlight'
elif name == 'inbox' and boxName in userPages:
classStr = 'tab-highlight'
if 'class' in config:
classStr += ' ' + config['class']
textStr = translate[config['translateText']]
navStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
f'\t\t\t\t\t<li>{textStr}</li>\n'
f'\t\t\t\t</a>\n')
navStr += '\t\t\t</ul>\n\t\t</div>\n'
return navStr