From 3ffb1e6524764f2d0105ab55cbb370efb5931840 Mon Sep 17 00:00:00 2001 From: The Dod Date: Sun, 6 Apr 2014 09:47:00 +0700 Subject: [PATCH] User fullname and avatar are now in an iframe Great performance boost. Also: * Input field to copy @username Once we can post, this may be handy * Search is also an iframe (containing an iframe per user) So you can keep composing a twist while searching for usernames * Should be responsive for cellulars (I can only resize browser to check. Got no phone. Anyway, the floating "Fork me" footer now has a link to navigation (local users), and that's about all the essential navigation. You can scroll a bit down from there for search results, or all the way up for the content. * Make sure Dillo etc. that don't see bootstrap font icon can still have text links to everything Enjoy --- static/assets/css/swizzler.css | 3 +- swizzler.py | 79 ++++++++++++++++++---------------- templates/footer.html | 3 +- templates/message.html | 66 +++++++++++++--------------- templates/messages.html | 40 ++++++----------- templates/sidebar.html | 37 ++++++---------- templates/standard.html | 40 +++++++++-------- templates/twist.html | 16 +++---- twister.py | 15 ++++--- 9 files changed, 142 insertions(+), 157 deletions(-) diff --git a/static/assets/css/swizzler.css b/static/assets/css/swizzler.css index de616db..0f885eb 100644 --- a/static/assets/css/swizzler.css +++ b/static/assets/css/swizzler.css @@ -1,5 +1,6 @@ body {padding-top:8px; background:#eef url(/assets/img/swizzler-128.png) no-repeat fixed right bottom} .avatar {max-width:64px; max-height:64px} .avatars32 .avatar {max-width:32px; max-height:32px} +.avatars42 .avatar {max-width:44px; max-height:44px} .panel, .list-group-item { background-color: rgba(255,255,255,0.33) } /* I should be doing this by customizing bootstrap. Later :) */ -#footer {z-index:115;position:fixed;right:123px;bottom:0} +#footer {z-index:115;position:fixed;right:96px;bottom:8px} diff --git a/swizzler.py b/swizzler.py index 9960c19..bbee32d 100644 --- a/swizzler.py +++ b/swizzler.py @@ -12,19 +12,19 @@ from ttp import ttp class TwistParser(ttp.Parser): def format_tag(self, tag, text): '''Return formatted HTML for a hashtag.''' - return '{2}{3}'.format( + return '{2}{3}'.format( cherrypy.request.base+cherrypy.request.script_name, ttp.urllib.quote(text.lower().encode('utf-8'),'xmlcharrefreplace'), tag, text) def format_username(self, at_char, user): '''Return formatted HTML for a username.''' - return '{2}{3}'.format( + return '{2}{3}'.format( cherrypy.request.base+cherrypy.request.script_name, user, at_char, user.lower()) def format_list(self, at_char, user, list_name): '''We don't have lists, so we see it as "@user" followed by "/something"''' - return '{2}{3}/{4}'.format( + return '{2}{3}/{4}'.format( cherrypy.request.base+cherrypy.request.script_name, cherrypy.request.base+cherrypy.request.script_name, user, at_char, user.lower(), list_name) @@ -45,47 +45,47 @@ def format_trending(twister,num_messages=8): ### The Swizzler app class SwizzlerApp(object): - def _standard_params(self,twister,q,num_items=8): + @cherrypy.expose + def search(self,q=''): + conf = cherrypy.request.app.config['swizzler'] + twister = Twister(conf['rpc_url'],format_twist) result = {'site_root':cherrypy.request.base+cherrypy.request.script_name} - result['here'] = result['site_root']+cherrypy.request.path_info - q=(q or '').strip().split(' ')[0] # ignore anything after the first space if any + q = q.strip().split(' ')[0] # ignore anything after the first space if any if q.startswith('#'): # user said "#sometag", change to "sometag" q=q[1:] if q and not q.startswith('@'): # Tag. redirect. raise cherrypy.HTTPRedirect(result['site_root']+'/tag/{0}'.format(q)) if q: result['user_prefix'] = q - result['users'] = twister.get_users_by_partial_name(q[1:],num_items) - return result - result['trending'] = format_trending(twister,num_items) - return result - + result['users'] = twister.get_users_by_partial_name(q[1:],conf['num_messages']) + else: + result['trending'] = format_trending(twister,conf['num_messages']) + return stache.render(stache.load_template('search'),result) + @cherrypy.expose - def twist(self,username,k,q=None): + def twist(self,username,k): conf = cherrypy.request.app.config['swizzler'] twister = Twister(conf['rpc_url'],format_twist) - params = self._standard_params(twister,q,conf['num_messages']) # called as soon as possible, because it might raise a redirect twist = twister.get_twist(username,k) + twist['style_large'] = True rts = twister.get_twist_rts(username,k) - print rts result = { 'is_twist':True, - 'title':u"@{0}: {1} - Swizzler".format(twist['user']['username'],twist['time']), + 'title':u"@{0}: {1} - Swizzler".format(username,twist['time']), 'twist':twist, - 'in_reply_to':twist.get('reply') and twister.get_twist(twist['reply']['user']['username'],twist['reply']['k']) or None, + 'in_reply_to':twist.get('reply') and twister.get_twist(twist['reply']['username'],twist['reply']['k']) or None, 'replies':twister.get_twist_replies(username,k), 'rts':rts, 'any_rts':not not rts, 'local_users':twister.local_user_menu()['users'], 'info':twister.get_info(), + 'site_root':cherrypy.request.base+cherrypy.request.script_name, } - result.update(params) return stache.render(stache.load_template('twist'),result) @cherrypy.expose - def user(self,username,q=None): + def user(self,username): conf = cherrypy.request.app.config['swizzler'] twister = Twister(conf['rpc_url'],format_twist) - params = self._standard_params(twister,q,conf['num_messages']) # called as soon as possible, because it might raise a redirect user = twister.get_user_info(username) messages = twister.get_user_posts(username,conf['num_messages']) result = { @@ -96,14 +96,26 @@ class SwizzlerApp(object): 'any_messages':not not messages, 'local_users':twister.local_user_menu()['users'], 'info':twister.get_info(), + 'site_root':cherrypy.request.base+cherrypy.request.script_name, } - result.update(params) return stache.render(stache.load_template('standard'),result) @cherrypy.expose - def tag(self,tag,q=None): + def user_embed(self,username='nobody',style='normal'): + if username=='nobody': username='' # to enable /nobody/large + conf = cherrypy.request.app.config['swizzler'] + twister = Twister(conf['rpc_url'],format_twist) + user = twister.get_user_info(username) + result = { + 'title':'@{0} - Swizzler'.format(username), + 'site_root':cherrypy.request.base+cherrypy.request.script_name, + 'user':twister.get_user_info(username) + } + result['style_{0}'.format(style)] = True + return stache.render(stache.load_template('user-iframe'),result) + @cherrypy.expose + def tag(self,tag): conf = cherrypy.request.app.config['swizzler'] twister = Twister(conf['rpc_url'],format_twist) - params = self._standard_params(twister,q,conf['num_messages']) # called as soon as possible, because it might raise a redirect messages = twister.get_tag_posts(tag) result = { 'is_tag':True, @@ -113,15 +125,13 @@ class SwizzlerApp(object): 'any_messages':not not messages, 'local_users':twister.local_user_menu()['users'], 'info':twister.get_info(), - #the filter avoids some utf etc. that ttf can't handle (TODO: fix or replace format_twist) + 'site_root':cherrypy.request.base+cherrypy.request.script_name, } - result.update(params) return stache.render(stache.load_template('standard'),result) @cherrypy.expose - def home(self,localusername,mode='feed',q=None): + def home(self,localusername,mode='feed'): conf = cherrypy.request.app.config['swizzler'] twister = Twister(conf['rpc_url'],format_twist) - params = self._standard_params(twister,q,conf['num_messages']) # called as soon as possible, because it might raise a redirect menu = twister.local_user_menu(localusername) if mode=='mentions': messages = twister.get_user_mentions(localusername) @@ -131,20 +141,19 @@ class SwizzlerApp(object): 'is_home':True, 'is_mentions':mode=='mentions', 'is_feed':mode!='mentions', - 'title':u"{fullname} (@{username}): Home - Swizzler".format(**menu['active']), + 'title':u"{fullname} (@{username}): {mode} - Swizzler".format(mode=mode=='mentions' and 'Mentions' or 'Home',**menu['active']), 'local_users':menu['users'], 'info':twister.get_info(), 'subject':menu['active'], 'messages':messages, 'any_messages':not not messages, + 'site_root':cherrypy.request.base+cherrypy.request.script_name, } - result.update(params) return stache.render(stache.load_template('standard'),result) @cherrypy.expose - def messages(self,localusername,remoteusername=None,q=None): + def messages(self,localusername,remoteusername=None): conf = cherrypy.request.app.config['swizzler'] twister = Twister(conf['rpc_url'],format_twist) - params = self._standard_params(twister,q,conf['num_messages']) # called as soon as possible, because it might raise a redirect localuser = twister.get_user_info(localusername) remoteuser = remoteusername and twister.get_user_info(remoteusername) or None threads = remoteusername and twister.get_user_messages(localusername,remoteusername,conf['num_messages']) or twister.get_user_messages(localusername) @@ -158,18 +167,17 @@ class SwizzlerApp(object): 'any_threads':not not threads, 'local_users':twister.local_user_menu()['users'], 'info':twister.get_info(), - #the filter avoids some utf etc. that ttf can't handle (TODO: fix or replace format_twist) + 'site_root':cherrypy.request.base+cherrypy.request.script_name, } - result.update(params) return stache.render(stache.load_template('messages'),result) @cherrypy.expose - def index(self,q=None): + def index(self): conf = cherrypy.request.app.config['swizzler'] twister = Twister(conf['rpc_url'],format_twist) - params = self._standard_params(twister,q,conf['num_messages']) # called as soon as possible, because it might raise a redirect messages = twister.get_sponsored_posts(conf['num_messages']) result = { 'is_user':True, # i.e. we want to display "bio" and not mentions/DMs/profile buttons + 'is_sponsored':True, # message template needs to know not to show "permalink" 'title':"Welcome to Swizzler", 'local_users':twister.local_user_menu('')['users'], # '' means: "Nobody" is active 'info':twister.get_info(), @@ -184,9 +192,8 @@ Start mining today, and all this (AND moral satisfaction) can be yours.""") }, 'messages':messages, 'any_messages':not not messages, - #the filter avoids some utf etc. that ttf can't handle (TODO: fix or replace format_twist) + 'site_root':cherrypy.request.base+cherrypy.request.script_name, } - result.update(params) return stache.render(stache.load_template('standard'),result) if __name__ == '__main__': diff --git a/templates/footer.html b/templates/footer.html index 61ef420..18e921c 100644 --- a/templates/footer.html +++ b/templates/footer.html @@ -1,3 +1,4 @@ diff --git a/templates/message.html b/templates/message.html index e60f33c..f48cd37 100644 --- a/templates/message.html +++ b/templates/message.html @@ -1,45 +1,37 @@
  • - {{#user}} + +
    {{#username}} - - {{fullname}} - +
    + {{^threads}} + + {{^is_sponsored}}{{/is_sponsored}}{{time}}{{^is_sponsored}}{{/is_sponsored}} + + {{/threads}} + {{#rt_username}} + + @{{.}} + + + {{/rt_username}} + @{{username}} + {{^is_twist}}{{#reply}} + + + @{{username}} + + {{/reply}}{{/is_twist}} +
    {{/username}} {{^username}} - - {{fullname}} - +
    + {{time}} + @{{username}} +
    {{/username}} - {{/user}} -
    - {{#user}} - {{#username}} -
    - - {{time}} - - {{#rt_user}} - - {{fullname}} - - - {{/rt_user}} - {{fullname}} - {{^is_twist}}{{#reply}} - - - {{#user}}{{fullname}}{{/user}} - - {{/reply}}{{/is_twist}} -
    - {{/username}} - {{^username}} -
    - {{time}} - {{fullname}} -
    - {{/username}} - {{/user}} {{{message}}}
  • diff --git a/templates/messages.html b/templates/messages.html index 97d5078..f57087c 100644 --- a/templates/messages.html +++ b/templates/messages.html @@ -1,5 +1,5 @@ - + @@ -22,22 +22,18 @@ {{fullname}}
    -

    - + + > {{fullname}}'s direct messages - {{#remoteuser}}with {{fullname}}{{/remoteuser}} + {{#remoteuser}}with {{fullname}}{{/remoteuser}} +

    +

    + Home + Mentions + Profile

    - {{#remoteuser}} - {{#subject}} - - {{/subject}} - {{/remoteuser}} - - -
    {{/subject}} @@ -49,21 +45,13 @@