__filename__ = "webapp_headerbuttons.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.1.0" __maintainer__ = "Bob Mottram" __email__ = "bob@freedombone.net" __status__ = "Production" import os import time from datetime import datetime from happening import todaysEventsCheck from happening import thisWeeksEventsCheck from webapp_utils import htmlHighlightLabel def headerButtonsTimeline(defaultTimeline: str, boxName: str, pageNumber: int, translate: {}, usersPath: str, mediaButton: str, blogsButton: str, featuresButton: str, newsButton: str, inboxButton: str, dmButton: str, newDM: str, repliesButton: str, newReply: str, minimal: bool, sentButton: str, sharesButtonStr: str, bookmarksButtonStr: str, eventsButtonStr: str, moderationButtonStr: str, newPostButtonStr: str, baseDir: str, nickname: str, domain: str, timelineStartTime, iconsAsButtons: bool, userPages: []) -> str: """Returns the header at the top of the timeline, containing buttons for inbox, outbox, search, calendar, etc """ # start of the button header with inbox, outbox, etc # TODO: [rename] containerHeader -> menu (or similar) tlStr = '\t
\n' # 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/' + \ 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
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 todaysEventsCheck(baseDir, nickname, domain): 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'} )) # NOTE: CSS used to show or hide these based on screen size activeButtonList.append(('newswire', {'pageRef': '/newswiremobile', 'translateText': 'Newswire', 'class': 'mobile-view', 'iconClass': 'icon-newswire'} )) activeButtonList.append(('links', {'pageRef': '/linksmobile', 'translateText': 'Edit Links', 'class': 'mobile-view', '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-' 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'} )) # TODO: Less hacky solution - or make sure "settings" button has an icon if defaultTimeline == 'tlnews': activeButtonList.append(('editprofile', {'pageRef': '/editprofile', 'translateText': 'Settings'} )) else: activeButtonList.append(('minimal', {'pageRef': '/minimal', 'translateText': 'Show/Hide Buttons', 'iconClass': 'icon-showhide'} )) # Generate HTML lists navButtonStr = "" if navButtonList: navButtonStr += '\t\t\n' navIconStr = "" if navIconList: navIconStr += '\t\t
\n' navIconStr += '\t\t\t
    \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\n" f'\t\t\t\t\t
  • {textStr}
  • \n' f'\t\t\t\t
    \n') navIconStr += '\t\t\t
\n\t\t
\n' # benchmark 5 timeDiff = int((time.time() - timelineStartTime) * 1000) if timeDiff > 100: print('TIMELINE TIMING ' + boxName + ' 5 = ' + str(timeDiff)) # Compile HTML parts tlStr += navButtonStr + navIconStr # End header button section tlStr += '\t
\n' 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', 'class': 'tab-news'} )) # navTabList.append(('calendar', # {'pageRef': '/calendar', # 'translateText': 'Calendar'} # )) navTabList.append(('linksmobile', {'pageRef': '/linksmobile', 'translateText': 'Links', 'class': 'tab-links'} )) navTabList.append(('inbox', {'pageRef': '/inbox', 'translateText': 'User'} )) navStr = '\t\t\n' return navStr