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 ?
baseDir + '/accounts/' + \ # - Are there others elsewhere in the code ?
nickname + '@' + domain + '/tlreplies.index'
if os.path.isfile(repliesIndexFilename):
tlStr += \
'<a href="' + usersPath + '/tlreplies"><button class="' + \
repliesButton + '"><span>' + \
htmlHighlightLabel(translate['Replies'], newReply) + \
'</span></button></a>'
# typically the media button # All menu items default to text buttons
if defaultTimeline != 'tlmedia': # Add class "icon-button" to overwrite default behaviour
if not minimal and not featuresHeader: # NOTE: Currently handled further down in loops over navButtonList and navIconList
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: # Menu buttons are split into two sections
# typically the blogs button # - Navigation buttons : Informational pages, e.g. Inbox
# but may change if this is a blogging oriented instance # - Action buttons : More clear action, e.g. Search, Create Post
if defaultTimeline != 'tlblogs': # default appearance text; use CSS class(es) to re-style
if not minimal:
titleStr = translate['Blogs']
if defaultTimeline == 'tlfeatures':
titleStr = translate['Article']
tlStr += \
'<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 # A list of buttons to be rendered as html,
# but may change if this is a news oriented instance # each item being a tuple containing
if defaultTimeline == 'tlfeatures': # - ref name
if not featuresHeader: # - dictionary of unique config
tlStr += \ # Each dict has:
'<a href="' + usersPath + \ # - pageRef : the url snippet
'/inbox"><button class="' + \ # - translationText : text to be displayed
inboxButton + '"><span>' + translate['Inbox'] + \ # - highlightLabel : boolean to determine highlight
'</span></button></a>' # - 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
# show todays events buttons on the first inbox page # Buttons should be added in the order you wish them to appear in the menu
happeningStr = '' 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/' + \
nickname + '@' + domain + '/followrequests.txt'
if os.path.isfile(followRequestsFilename):
with open(followRequestsFilename, 'r') as f:
for line in f:
if len(line) > 0:
# show follow approvals icon
followApprovals = True
break
# NOTE: Certain buttons only appear when relevant
# TODO: Determine if approvals (currently appended at end of activeButtonList)
# and events should be in a separate list;
# e.g. notificationButtonList
# Having its' own <div> for instance would allow more versatile styling
if followApprovals:
activeButtonList.append(('followers',
{'pageRef': '/followers',
'translateText': 'Approve follow requests',
'iconClass': 'icon-newfollow'}
))
# Only show todays events buttons on the first inbox page
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) + \
'?month=' + str(now.month) + \
'?day=' + str(now.day)
activeButtonList.append(('today-event',
{'pageRef': todayRef,
'translateText': 'Happening Today',
'class': 'button-event'}
))
if thisWeeksEventsCheck(baseDir, nickname, domain):
activeButtonList.append(('week-event',
{'pageRef': '/calendar',
'translateText': 'Happening Today',
'class': 'button-event'}
))
# happening today button
if not iconsAsButtons: # NOTE: CSS used to show or hide these based on screen size
happeningStr += \ activeButtonList.append(('newswire',
'<a href="' + usersPath + '/calendar?year=' + \ {'pageRef': '/newswiremobile',
str(now.year) + '?month=' + str(now.month) + \ 'translateText': 'Newswire',
'?day=' + str(now.day) + '">' + \ 'class': 'mobile-only',
'<button class="buttonevent">' + \ 'iconClass': 'icon-newswire'}
translate['Happening Today'] + '</button></a>' ))
activeButtonList.append(('links',
{'pageRef': '/linksmobile',
'translateText': 'Edit Links',
'class': 'mobile-only',
'iconClass': 'icon-links'}
))
# what screen to go to when a new post is created
# The following produces one button/icon for "new post" dependent on current viewed page
if boxName == 'dm':
activeButtonList.append(('newdm',
{'pageRef': '/newdm',
'translateText': 'Create a new DM'}
))
elif boxName == 'tlblogs' or boxName == 'tlnews':
activeButtonList.append(('newblog',
{'pageRef': '/newblog',
'translateText': 'Create a new post'}
))
elif boxName == 'tlevents':
activeButtonList.append(('newevent',
{'pageRef': '/newevent',
'translateText': 'Create a new event'}
))
else:
if not manuallyApproveFollowers:
activeButtonList.append(('newpost',
{'pageRef': '/newpost',
'translateText': 'Create a new post'}
))
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: else:
happeningStr += \ if name == boxName:
'<a href="' + usersPath + '/calendar?year=' + \ classStr += ' button-selected'
str(now.year) + '?month=' + str(now.month) + \ textStr += translate[config['translateText']]
'?day=' + str(now.day) + '">' + \
'<button class="button">' + \ navButtonStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
translate['Happening Today'] + '</button></a>' 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'
# happening this week button navIconStr = ""
if thisWeeksEventsCheck(baseDir, nickname, domain): if navIconList:
if not iconsAsButtons: navIconStr += '\t\t<div class="actionbuttons">\n'
happeningStr += \ navIconStr += '\t\t\t<ul class="button-bar">\n'
'<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>'
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: # TODO: [rename] 'timelineicon' should maybe be more generic, e.g 'icon-button'
# button for the outbox
tlStr += \
'<a href="' + usersPath + \
'/outbox"><button class="' + \
sentButton + '"><span>' + translate['Outbox'] + \
'</span></button></a>'
# add other buttons # Generate HTML list
tlStr += \ for name, config in navIconList:
sharesButtonStr + bookmarksButtonStr + eventsButtonStr + \ if iconsAsButtons:
moderationButtonStr + happeningStr + newPostButtonStr 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 not featuresHeader: if 'class' in config:
if not iconsAsButtons: classStr += ' ' + config['class']
# the search icon
tlStr += \ if 'highlightLabel' in config:
'<a class="imageAnchor" href="' + usersPath + \ textStr = htmlHighlightLabel(translate[config['translateText']], config['highlightLabel'])
'/search"><img loading="lazy" src="/' + \ else:
'icons/search.png" title="' + \ textStr = translate[config['translateText']]
translate['Search and follow'] + '" alt="| ' + \
translate['Search and follow'] + \ navIconStr += (f"\t\t\t\t<a class=\"{classStr}\" href=\"{usersPath}{config['pageRef']}\">\n"
'" class="timelineicon"/></a>' f'\t\t\t\t\t<li>{textStr}</li>\n'
else: f'\t\t\t\t</a>\n')
# the search button
tlStr += \ navIconStr += '\t\t\t</ul>\n\t\t</div>\n'
'<a href="' + usersPath + \
'/search"><button class="button">' + \
'<span>' + translate['Search'] + \
'</span></button></a>'
# 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