Set position of rss icon within the timeline

main
Bob Mottram 2020-10-26 20:32:01 +00:00
parent 05a4c58395
commit 0b02565159
5 changed files with 121 additions and 44 deletions

View File

@ -6475,7 +6475,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
if GETstartTime:
self._benchmarkGETtimings(GETstartTime, GETtimings,
'show status done',
@ -6594,7 +6595,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -6706,7 +6708,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -6818,7 +6821,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -6930,7 +6934,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -7051,7 +7056,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -7131,7 +7137,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
self.server.fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -7227,7 +7234,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -7342,7 +7350,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -7449,7 +7458,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -7546,7 +7556,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.positiveVoting,
self.server.showPublishAsIcon,
fullWidthTimelineButtonHeader,
self.server.iconsAsButtons)
self.server.iconsAsButtons,
self.server.rssIconAtTop)
msg = msg.encode('utf-8')
self._set_headers('text/html', len(msg),
cookie, callingDomain)
@ -12062,7 +12073,8 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None:
tokensLookup[token] = nickname
def runDaemon(iconsAsButtons: bool,
def runDaemon(rssIconAtTop: bool,
iconsAsButtons: bool,
fullWidthTimelineButtonHeader: bool,
showPublishAsIcon: bool,
maxFollowers: int,
@ -12231,6 +12243,9 @@ def runDaemon(iconsAsButtons: bool,
# whether to show icons in the header (eg calendar) as buttons
httpd.iconsAsButtons = iconsAsButtons
# whether to show the RSS icon at the top or the bottom of the timeline
httpd.rssIconAtTop = rssIconAtTop
if registration == 'open':
httpd.registration = True
else:

View File

@ -232,6 +232,12 @@ parser.add_argument("--iconsAsButtons",
type=str2bool, nargs='?',
const=True, default=False,
help="Show header icons as buttons")
parser.add_argument("--rssIconAtTop",
dest='rssIconAtTop',
type=str2bool, nargs='?',
const=True, default=True,
help="Whether to show the rss icon at teh top or bottom" +
"of the timeline")
parser.add_argument("--noapproval", type=str2bool, nargs='?',
const=True, default=False,
help="Allow followers without approval")
@ -2013,6 +2019,11 @@ iconsAsButtons = \
if iconsAsButtons is not None:
args.iconsAsButtons = bool(iconsAsButtons)
rssIconAtTop = \
getConfigParam(baseDir, 'rssIconAtTop')
if rssIconAtTop is not None:
args.rssIconAtTop = bool(rssIconAtTop)
fullWidthTimelineButtonHeader = \
getConfigParam(baseDir, 'fullWidthTimelineButtonHeader')
if fullWidthTimelineButtonHeader is not None:
@ -2031,7 +2042,8 @@ if setTheme(baseDir, themeName, domain):
print('Theme set to ' + themeName)
if __name__ == "__main__":
runDaemon(args.iconsAsButtons,
runDaemon(args.rssIconAtTop,
args.iconsAsButtons,
args.fullWidthTimelineButtonHeader,
args.showPublishAsIcon,
args.maxFollowers,

View File

@ -291,7 +291,8 @@ def createServerAlice(path: str, domain: str, port: int,
onionDomain = None
i2pDomain = None
print('Server running: Alice')
runDaemon(False, False, True, 10, False, 0, 100, 1024, 5, False,
runDaemon(True, False, False, True, 10, False,
0, 100, 1024, 5, False,
0, False, 1, False, False, False,
5, True, True, 'en', __version__,
"instanceId", False, path, domain,
@ -355,7 +356,8 @@ def createServerBob(path: str, domain: str, port: int,
onionDomain = None
i2pDomain = None
print('Server running: Bob')
runDaemon(False, False, True, 10, False, 0, 100, 1024, 5, False, 0,
runDaemon(True, False, False, True, 10, False,
0, 100, 1024, 5, False, 0,
False, 1, False, False, False,
5, True, True, 'en', __version__,
"instanceId", False, path, domain,
@ -393,7 +395,8 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
onionDomain = None
i2pDomain = None
print('Server running: Eve')
runDaemon(False, False, True, 10, False, 0, 100, 1024, 5, False, 0,
runDaemon(True, False, False, True, 10, False,
0, 100, 1024, 5, False, 0,
False, 1, False, False, False,
5, True, True, 'en', __version__,
"instanceId", False, path, domain,

View File

@ -68,6 +68,19 @@ def setIconsAsButtons(baseDir: str, useButtons: bool) -> bool:
return saveJson(configJson, configFilename)
def setRssIconAtTop(baseDir: str, atTop: bool) -> bool:
"""Whether to show RSS icon at the top of the timeline
"""
configFilename = baseDir + '/config.json'
if not os.path.isfile(configFilename):
return False
configJson = loadJson(configFilename, 0)
if not configJson:
return False
configJson['rssIconAtTop'] = atTop
return saveJson(configJson, configFilename)
def setFullWidthTimelineButtonHeader(baseDir: str, fullWidth: bool) -> bool:
"""Shows the timeline button header containing inbox, outbox,
calendar, etc as full width
@ -276,6 +289,7 @@ def setThemeDefault(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
bgParams = {
"login": "jpg",
"follow": "jpg",
@ -295,6 +309,7 @@ def setThemeIndymediaClassic(baseDir: str):
setNewswirePublishAsIcon(baseDir, False)
setFullWidthTimelineButtonHeader(baseDir, True)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
bgParams = {
"login": "jpg",
"follow": "jpg",
@ -377,6 +392,7 @@ def setThemeBlue(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
themeParams = {
"newswire-date-color": "blue",
"font-size-header": "22px",
@ -417,6 +433,7 @@ def setThemeNight(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
fontStr = \
"url('./fonts/solidaric.woff2') format('woff2')"
fontStrItalic = \
@ -478,6 +495,7 @@ def setThemeStarlight(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
themeParams = {
"column-left-image-width-mobile": "40vw",
"line-spacing-newswire": "120%",
@ -548,6 +566,7 @@ def setThemeHenge(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
themeParams = {
"column-left-image-width-mobile": "40vw",
"column-right-image-width-mobile": "40vw",
@ -613,6 +632,7 @@ def setThemeZen(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
themeParams = {
"main-bg-color": "#5c4e41",
"column-left-color": "#5c4e41",
@ -674,6 +694,7 @@ def setThemeHighVis(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
def setThemeLCD(baseDir: str):
@ -755,6 +776,7 @@ def setThemeLCD(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
def setThemePurple(baseDir: str):
@ -819,6 +841,7 @@ def setThemePurple(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
def setThemeHacker(baseDir: str):
@ -880,6 +903,7 @@ def setThemeHacker(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
def setThemeLight(baseDir: str):
@ -942,6 +966,7 @@ def setThemeLight(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
def setThemeIndymediaModern(baseDir: str):
@ -1038,6 +1063,7 @@ def setThemeIndymediaModern(baseDir: str):
setNewswirePublishAsIcon(baseDir, False)
setFullWidthTimelineButtonHeader(baseDir, True)
setIconsAsButtons(baseDir, True)
setRssIconAtTop(baseDir, False)
def setThemeSolidaric(baseDir: str):
@ -1106,6 +1132,7 @@ def setThemeSolidaric(baseDir: str):
setNewswirePublishAsIcon(baseDir, True)
setFullWidthTimelineButtonHeader(baseDir, False)
setIconsAsButtons(baseDir, False)
setRssIconAtTop(baseDir, True)
def setThemeImages(baseDir: str, name: str) -> None:

View File

@ -3612,7 +3612,8 @@ def htmlProfile(defaultTimeline: str,
httpPrefix, translate,
iconsDir, False, False,
newswire, False,
False, None, False, False)
False, None, False, False,
False)
profileFooterStr += ' </td>\n'
profileFooterStr += ' </tr>\n'
profileFooterStr += ' </tbody>\n'
@ -5701,7 +5702,8 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
newswire: {}, positiveVoting: bool,
showBackButton: bool, timelinePath: str,
showPublishButton: bool,
showPublishAsIcon: bool) -> str:
showPublishAsIcon: bool,
rssIconAtTop: bool) -> str:
"""Returns html content for the right column
"""
htmlStr = ''
@ -5775,13 +5777,15 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
translate['Edit newswire'] + '" src="/' + \
iconsDir + '/edit.png" /></a>\n'
htmlStr += \
rssIconStr = \
' <a href="/newswire.xml">' + \
'<img class="' + editImageClass + \
'" loading="lazy" alt="' + \
translate['Newswire RSS Feed'] + '" title="' + \
translate['Newswire RSS Feed'] + '" src="/' + \
iconsDir + '/logorss.png" /></a>\n'
if rssIconAtTop:
htmlStr += rssIconStr
if showPublishButton:
if showPublishAsIcon:
@ -5801,6 +5805,9 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
htmlStr += htmlNewswire(newswire, nickname, moderator, translate,
positiveVoting, iconsDir)
if not rssIconAtTop:
htmlStr += rssIconStr
return htmlStr
@ -5883,7 +5890,7 @@ def htmlNewswireMobile(baseDir: str, nickname: str,
iconsDir, moderator, editor,
newswire, positiveVoting,
True, timelinePath, True,
showPublishAsIcon)
showPublishAsIcon, True)
htmlStr += htmlFooter()
return htmlStr
@ -6204,7 +6211,8 @@ def htmlTimeline(defaultTimeline: str,
positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the timeline as html
"""
timelineStartTime = time.time()
@ -6728,7 +6736,8 @@ def htmlTimeline(defaultTimeline: str,
moderator, editor,
newswire, positiveVoting,
False, None, True,
showPublishAsIcon)
showPublishAsIcon,
rssIconAtTop)
tlStr += ' <td valign="top" class="col-right">' + \
rightColumnStr + ' </td>\n'
tlStr += ' </tr>\n'
@ -6774,7 +6783,8 @@ def htmlShares(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the shares timeline as html
"""
manuallyApproveFollowers = \
@ -6791,7 +6801,7 @@ def htmlShares(defaultTimeline: str,
newswire, False, False,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlInbox(defaultTimeline: str,
@ -6806,7 +6816,8 @@ def htmlInbox(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the inbox as html
"""
manuallyApproveFollowers = \
@ -6823,7 +6834,7 @@ def htmlInbox(defaultTimeline: str,
newswire, False, False,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlBookmarks(defaultTimeline: str,
@ -6838,7 +6849,8 @@ def htmlBookmarks(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the bookmarks as html
"""
manuallyApproveFollowers = \
@ -6855,7 +6867,7 @@ def htmlBookmarks(defaultTimeline: str,
newswire, False, False,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlEvents(defaultTimeline: str,
@ -6870,7 +6882,8 @@ def htmlEvents(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the events as html
"""
manuallyApproveFollowers = \
@ -6887,7 +6900,7 @@ def htmlEvents(defaultTimeline: str,
newswire, False, False,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlInboxDMs(defaultTimeline: str,
@ -6902,7 +6915,8 @@ def htmlInboxDMs(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the DM timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
@ -6914,7 +6928,7 @@ def htmlInboxDMs(defaultTimeline: str,
newswire, False, False, positiveVoting,
showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlInboxReplies(defaultTimeline: str,
@ -6929,7 +6943,8 @@ def htmlInboxReplies(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the replies timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
@ -6942,7 +6957,7 @@ def htmlInboxReplies(defaultTimeline: str,
newswire, False, False,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlInboxMedia(defaultTimeline: str,
@ -6957,7 +6972,8 @@ def htmlInboxMedia(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the media timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
@ -6970,7 +6986,7 @@ def htmlInboxMedia(defaultTimeline: str,
newswire, False, False,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlInboxBlogs(defaultTimeline: str,
@ -6985,7 +7001,8 @@ def htmlInboxBlogs(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the blogs timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
@ -6998,7 +7015,7 @@ def htmlInboxBlogs(defaultTimeline: str,
newswire, False, False,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlInboxNews(defaultTimeline: str,
@ -7013,7 +7030,8 @@ def htmlInboxNews(defaultTimeline: str,
newswire: {}, moderator: bool, editor: bool,
positiveVoting: bool, showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the news timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
@ -7026,7 +7044,7 @@ def htmlInboxNews(defaultTimeline: str,
newswire, moderator, editor,
positiveVoting, showPublishAsIcon,
fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlModeration(defaultTimeline: str,
@ -7041,7 +7059,8 @@ def htmlModeration(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the moderation feed as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
@ -7052,7 +7071,7 @@ def htmlModeration(defaultTimeline: str,
YTReplacementDomain, showPublishedDateOnly,
newswire, False, False, positiveVoting,
showPublishAsIcon, fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlOutbox(defaultTimeline: str,
@ -7067,7 +7086,8 @@ def htmlOutbox(defaultTimeline: str,
newswire: {}, positiveVoting: bool,
showPublishAsIcon: bool,
fullWidthTimelineButtonHeader: bool,
iconsAsButtons: bool) -> str:
iconsAsButtons: bool,
rssIconAtTop: bool) -> str:
"""Show the Outbox as html
"""
manuallyApproveFollowers = \
@ -7081,7 +7101,7 @@ def htmlOutbox(defaultTimeline: str,
YTReplacementDomain, showPublishedDateOnly,
newswire, False, False, positiveVoting,
showPublishAsIcon, fullWidthTimelineButtonHeader,
iconsAsButtons)
iconsAsButtons, rssIconAtTop)
def htmlIndividualPost(recentPostsCache: {}, maxRecentPosts: int,