diff --git a/webapp_column_right.py b/webapp_column_right.py index 502c51b9..89754612 100644 --- a/webapp_column_right.py +++ b/webapp_column_right.py @@ -14,6 +14,7 @@ from utils import locatePost from utils import loadJson from utils import votesOnNewswireItem from utils import getNicknameFromActor +from utils import getConfigParam from utils import isEditor from posts import isModerator from webapp_utils import getRightImageFile diff --git a/webapp_headerbuttons.py b/webapp_headerbuttons.py index 8e7799fe..d36bc4f8 100644 --- a/webapp_headerbuttons.py +++ b/webapp_headerbuttons.py @@ -20,22 +20,9 @@ def headerButtonsTimeline(defaultTimeline: 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, + moderator: bool, + manuallyApproveFollowers: bool, baseDir: str, nickname: str, domain: str, timelineStartTime, @@ -44,6 +31,53 @@ def headerButtonsTimeline(defaultTimeline: str, """Returns the header at the top of the timeline, containing buttons for inbox, outbox, search, calendar, etc """ + + accountDir = baseDir + '/accounts/' + nickname + '@' + domain + + # should the calendar icon be highlighted? + newCalendarEvent = False + calendarImage = 'calendar.png' + calendarPath = '/calendar' + calendarFile = accountDir + '/.newCalendar' + if os.path.isfile(calendarFile): + newCalendarEvent = True + calendarImage = 'calendar_notify.png' + with open(calendarFile, 'r') as calfile: + calendarPath = calfile.read().replace('##sent##', '') + calendarPath = calendarPath.replace('\n', '').replace('\r', '') + + # should the DM button be highlighted? + newDM = False + dmFile = accountDir + '/.newDM' + if os.path.isfile(dmFile): + newDM = True + if boxName == 'dm': + os.remove(dmFile) + + # should the Replies button be highlighted? + newReply = False + replyFile = accountDir + '/.newReply' + if os.path.isfile(replyFile): + newReply = True + if boxName == 'tlreplies': + os.remove(replyFile) + + # should the Shares button be highlighted? + newShare = False + newShareFile = accountDir + '/.newShare' + if os.path.isfile(newShareFile): + newShare = True + if boxName == 'tlshares': + os.remove(newShareFile) + + # should the Moderation/reports button be highlighted? + newReport = False + newReportFile = accountDir + '/.newReport' + if os.path.isfile(newReportFile): + newReport = True + if boxName == 'moderation': + os.remove(newReportFile) + # start of the button header with inbox, outbox, etc # TODO: [rename] containerHeader -> menu (or similar) diff --git a/webapp_timeline.py b/webapp_timeline.py index be03aa7e..fc481859 100644 --- a/webapp_timeline.py +++ b/webapp_timeline.py @@ -185,7 +185,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str, getLeftColumnContent(baseDir, nickname, domainFull, httpPrefix, translate, editor, False, None, rssIconAtTop, - True, False) + True, False, theme) tlStr += ' \n' @@ -353,6 +353,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str, if separatorStr: tlStr += separatorStr if boxName == 'tlmedia': + # Close galleryContainer tlStr += '\n' # page down arrow @@ -367,10 +368,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str, translate['Page down'] + '">\n' + \ ' \n' - # end of timeline-posts - tlStr += ' \n' - - # end of column-center + # end of 'section main' tlStr += ' \n' if defaultTimeline == 'tlfeatures' and boxName not in userPages: @@ -382,13 +380,15 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str, False, None, True, showPublishAsIcon, rssIconAtTop, publishButtonAtTop, - authorized, True) + authorized, True, theme) tlStr += '
' + \ rightColumnStr + '
\n' _logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '9') + # end of timeline tlStr += '\n' + tlStr += htmlFooter() return tlStr @@ -491,415 +491,6 @@ def htmlHighlightLabel(label: str, highlight: bool) -> str: return '*' + str(label) + '*' -def headerButtonsTimeline(defaultTimeline: str, - boxName: str, - pageNumber: int, - translate: {}, - usersPath: str, - minimal: bool, - moderator: bool, - manuallyApproveFollowers: bool, - baseDir: str, - nickname: str, domain: str, - timelineStartTime, - iconsAsButtons: bool) -> str: - """Returns the header at the top of the timeline, containing - buttons for inbox, outbox, search, calendar, etc - """ - - accountDir = baseDir + '/accounts/' + nickname + '@' + domain - - # should the calendar icon be highlighted? - newCalendarEvent = False - calendarImage = 'calendar.png' - calendarPath = '/calendar' - calendarFile = accountDir + '/.newCalendar' - if os.path.isfile(calendarFile): - newCalendarEvent = True - calendarImage = 'calendar_notify.png' - with open(calendarFile, 'r') as calfile: - calendarPath = calfile.read().replace('##sent##', '') - calendarPath = calendarPath.replace('\n', '').replace('\r', '') - - # should the DM button be highlighted? - newDM = False - dmFile = accountDir + '/.newDM' - if os.path.isfile(dmFile): - newDM = True - if boxName == 'dm': - os.remove(dmFile) - - # should the Replies button be highlighted? - newReply = False - replyFile = accountDir + '/.newReply' - if os.path.isfile(replyFile): - newReply = True - if boxName == 'tlreplies': - os.remove(replyFile) - - # should the Shares button be highlighted? - newShare = False - newShareFile = accountDir + '/.newShare' - if os.path.isfile(newShareFile): - newShare = True - if boxName == 'tlshares': - os.remove(newShareFile) - - # should the Moderation/reports button be highlighted? - newReport = False - newReportFile = accountDir + '/.newReport' - if os.path.isfile(newReportFile): - newReport = True - if boxName == 'moderation': - os.remove(newReportFile) - - - # 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 actionButtonList - - # 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 = [] - actionButtonList = [] - - # 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 - - navButtonList.append(('inbox', - {'pageRef': '/inbox', - 'translateText': 'Inbox'} - )) - navButtonList.append(('outbox', - {'pageRef': '/outbox', - 'translateText': 'Outbox'} - )) - navButtonList.append(('dm', - {'pageRef': '/dm', - 'translateText': 'DM', - 'highlightLabel': newDM} - )) - navButtonList.append(('tlreplies', - {'pageRef': '/tlreplies', - 'translateText': 'Replies', - 'highlightLabel': newReply} - )) - - if not minimal: - navButtonList.append(('tlnews', - {'pageRef': '/tlnews', - 'translateText': 'News'} - )) - # The following translationText should be 'Article' for News instances - navButtonList.append(('tlblogs', - {'pageRef': '/tlblogs', - 'translateText': 'Blogs'} - )) - navButtonList.append(('tlmedia', - {'pageRef': '/tlmedia', - 'translateText': 'Media'} - )) - navButtonList.append(('tlshares', - {'pageRef': '/tlshares', - 'translateText': 'Shares', - 'highlightLabel': newShare} - )) - navButtonList.append(('tlbookmarks', - {'pageRef': '/tlbookmarks', - 'translateText': 'Bookmarks'} - )) - navButtonList.append(('tlevents', - {'pageRef': '/tlevents', - 'translateText': 'Events'} - )) - if moderator: - navButtonList.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(navButtonList): - if name == defaultTimeline: - tmp = navButtonList.pop(i) - navButtonList.insert(0, tmp) - break - - # Generate HTML list - navButtonStr = '\t\t\n' - - - # start of headericons list - - # 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 actionButtonList) - # and events should be in a separate list; - # e.g. notificationButtonList - # Having its' own
for instance would allow more versatile styling - if followApprovals: - actionButtonList.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) - actionButtonList.append(('today-event', - {'pageRef': todayRef, - 'translateText': 'Happening Today', - 'class': 'button-event'} - )) - if thisWeeksEventsCheck(baseDir, nickname, domain): - actionButtonList.append(('week-event', - {'pageRef': '/calendar', - 'translateText': 'Happening Today', - 'class': 'button-event'} - )) - - - # NOTE: CSS used to show or hide these based on screen size - actionButtonList.append(('newswire', - {'pageRef': '/newswiremobile', - 'translateText': 'Newswire', - 'class': 'mobile-only', - 'iconClass': 'icon-newswire'} - )) - actionButtonList.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': - actionButtonList.append(('newdm', - {'pageRef': '/newdm', - 'translateText': 'Create a new DM'} - )) - elif boxName == 'tlblogs' or boxName == 'tlnews': - actionButtonList.append(('newblog', - {'pageRef': '/newblog', - 'translateText': 'Create a new post'} - )) - elif boxName == 'tlevents': - actionButtonList.append(('newevent', - {'pageRef': '/newevent', - 'translateText': 'Create a new event'} - )) - else: - if not manuallyApproveFollowers: - actionButtonList.append(('newpost', - {'pageRef': '/newpost', - 'translateText': 'Create a new post'} - )) - else: - actionButtonList.append(('newfollowers', - {'pageRef': '/newfollowers', - 'translateText': 'Create a new post'} - )) - # 'icon-' is solely used for the CSS to load appropriate icon - actionButtonList[-1][1]['iconClass'] = 'icon-newpost' - - actionButtonList.append(('calendar', - {'pageRef': calendarPath, - 'translateText': 'Calendar', - 'iconClass': 'icon-calendar'} - )) - actionButtonList.append(('search', - {'pageRef': '/search', - 'translateText': 'Search', - 'iconClass': 'icon-search'} - )) - actionButtonList.append(('minimal', - {'pageRef': '/minimal', - 'translateText': 'Show/Hide Buttons', - 'iconClass': 'icon-showhide'} - )) - - actionButtonStr = '\t\t
\n' - actionButtonStr += '\t\t\t
    \n' - - # TODO: [rename] 'timelineicon' should maybe be more generic, e.g 'icon-button' - - # Generate HTML list - for name, config in actionButtonList: - if iconsAsButtons: - classStr = 'button-test' - 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']] - - actionButtonStr += (f"\t\t\t\t\n" - f'\t\t\t\t\t
  • {textStr}
  • \n' - f'\t\t\t\t
    \n') - - actionButtonStr += '\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 + actionButtonStr - - # End header button section - tlStr += '\t
\n' - - return tlStr - - -def headerNewsTabs(boxName: str, - translate: {}, - usersPath: str, - moderator: bool, - baseDir: str) -> str: - navTabList = [] - - navTabList.append(('tlnews', - {'pageRef': '/tlnews', - 'translateText': 'Features'} - )) - navTabList.append(('newswiremobile', - {'pageRef': '/newswiremobile', - 'translateText': 'News'} - )) - navTabList.append(('calendar', - {'pageRef': '/calendar', - 'translateText': 'Calendar'} - )) - navTabList.append(('linksmobile', - {'pageRef': '/linksmobile', - 'translateText': 'Links'} - )) - navTabList.append(('inbox', - {'pageRef': '/inbox', - 'translateText': 'User'} - )) - - navStr = '\t\t\n' - - return navStr - - def htmlShares(cssCache: {}, defaultTimeline: str, recentPostsCache: {}, maxRecentPosts: int, translate: {}, pageNumber: int, itemsPerPage: int,