Skip to content

Commit 749ee77

Browse files
authored
Updates to support sticky site header (#822)
* Displays trimmed site header when scrolling upward and hides on scrolling downward. * Includes a notification badge for mobile. Kind of addresses #289 as a result. * Supports light / dark mode. * Updates mltshp-patterns CSS to v2.8.0.
1 parent 92c31bd commit 749ee77

File tree

8 files changed

+93
-28
lines changed

8 files changed

+93
-28
lines changed

handlers/home.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def get(self, before_or_after=None, base36_id=None, returning=None):
6565
else:
6666
front_page = True
6767
notifications = models.Notification.display_for_user(current_user_obj)
68+
notifications_count = notifications['total']
6869
sharedfiles = current_user_obj.sharedfiles_from_subscriptions(per_page=11)
6970
# Start Reading.
7071
first_bookmark = None

models/notification.py

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ class Notification(Model):
1919
type = Property() # favorite, save, subscriber
2020
deleted = Property(default=0)
2121
created_at = Property()
22-
22+
2323
def save(self, *args, **kwargs):
2424
if options.readonly:
2525
self.add_error('_', 'Site is read-only.')
2626
return False
2727

2828
self._set_dates()
2929
return super(Notification, self).save(*args, **kwargs)
30-
30+
3131
def _set_dates(self):
3232
"""
3333
Sets the created_at and updated_at fields. This should be something
@@ -39,13 +39,13 @@ def _set_dates(self):
3939
def delete(self):
4040
self.deleted = 1
4141
self.save()
42-
42+
4343
def sender(self):
4444
return user.User.get("id=%s", self.sender_id)
45-
45+
4646
def receiver(self):
4747
return user.User.get("id=%s", self.receiver_id)
48-
48+
4949
def related_object(self):
5050
"""
5151
Return the object this notification relates to. In the case of a favorite
@@ -63,7 +63,7 @@ def related_object(self):
6363
return subscription_ and subscription_.shake()
6464
else:
6565
return user.User.get("id = %s and deleted=0", self.sender_id)
66-
66+
6767
@classmethod
6868
def invitation_to_shake_for_user(self, shake, user):
6969
"""
@@ -117,51 +117,63 @@ def display_for_user(cls, user):
117117
'invitation':[],
118118
'invitations': [], # TODO: kill this ambiguity - IK
119119
'invitation_request' : [],
120-
'invitation_approved' : []
120+
'invitation_approved' : [],
121+
'total': 0,
121122
}
123+
total = 0
122124
for notification in cls.for_user(user):
123125
sender = notification.sender()
124126
related_object = notification.related_object()
125127
if not related_object:
126128
continue
127129

128130
_notification = {'sender' : sender, 'related_object' : related_object, 'id' : notification.id}
129-
131+
130132
if notification.type == 'favorite':
131133
if related_object.id not in notifications['like']['items']:
132134
notifications['like']['items'][related_object.id] = []
133135
notifications['like']['items'][related_object.id].append(_notification)
134136
notifications['like']['count'] += 1
135-
137+
total += 1
138+
136139
elif notification.type == 'subscriber':
137140
_notification['post_name_text'] = " is now following " + related_object.display_name(user)
138141
notifications['follow'].append(_notification)
139-
142+
total += 1
143+
140144
elif notification.type == 'save':
141145
if related_object.id not in notifications['save']['items']:
142146
notifications['save']['items'][related_object.id] = []
143147
notifications['save']['items'][related_object.id].append(_notification)
144148
notifications['save']['count'] += 1
149+
total += 1
145150

146151
elif notification.type == 'comment':
147152
notifications['comment'].append(_notification)
153+
total += 1
148154

149155
elif notification.type == 'mention':
150156
notifications['mention'].append(_notification)
157+
total += 1
151158

152159
elif notification.type == 'invitation':
153160
notifications['invitation'].append(_notification)
154-
161+
total += 1
162+
155163
elif notification.type == 'invitation_request':
156164
notifications['invitation_request'].append(_notification)
157-
165+
total += 1
166+
158167
elif notification.type == 'invitation_approved':
159168
notifications['invitation_approved'].append(_notification)
160-
169+
total += 1
170+
171+
notifications['total'] = total
172+
161173
#for invitation_ in invitation.Invitation.by_user(user):
162174
# notifications['invitations'].append(invitation_.email_address)
163175
return notifications
164-
176+
165177
@classmethod
166178
def for_user(cls, user, deleted=False):
167179
"""
@@ -192,7 +204,7 @@ def new_favorite(sender, sharedfile):
192204
n = Notification(sender_id=sender.id, receiver_id=sharedfile.user_id, action_id=sharedfile.id, type='favorite')
193205
n.save()
194206
return n
195-
207+
196208
@staticmethod
197209
def new_save(sender, sharedfile):
198210
"""
@@ -215,7 +227,7 @@ def new_comment(comment):
215227
n = Notification(sender_id=comment.user_id, receiver_id=sf.user_id, action_id=comment.id, type='comment')
216228
n.save()
217229
return n
218-
230+
219231
@staticmethod
220232
def new_comment_like(comment, sender):
221233
"""
@@ -237,7 +249,7 @@ def new_mention(receiver, comment):
237249
n = Notification(sender_id=comment.user_id, receiver_id=receiver.id, action_id=comment.id, type='mention')
238250
n.save()
239251
return n
240-
252+
241253
@staticmethod
242254
def new_invitation_request_accepted(sender, receiver, shake):
243255
"""
@@ -256,7 +268,7 @@ def new_invitation_to_shake(sender, receiver, action_id):
256268
action_id - the shake_id
257269
"""
258270
the_shake = shake.Shake.get('id=%s', action_id)
259-
271+
260272
n = Notification(sender_id=sender.id, receiver_id=receiver.id, action_id=action_id, type='invitation_request')
261273
text_message = """Hi, %s.
262274
%s has requested to join "%s". This means they will be able to put files into the "%s" shake.
@@ -325,7 +337,7 @@ def new_invitation(sender, receiver, action_id):
325337
""" % (receiver.name, options.app_host, sender.name, sender.display_name(), options.app_host,
326338
new_shake.name, new_shake.display_name(), options.app_host, new_shake.name,
327339
new_shake.display_name(), options.app_host, new_shake.name, options.app_host, new_shake.name)
328-
340+
329341
n.save()
330342

331343
if not receiver.disable_notifications and not options.debug:
@@ -336,7 +348,7 @@ def new_invitation(sender, receiver, action_id):
336348
html_body=html_message)
337349
pm.send()
338350
return n
339-
351+
340352
@staticmethod
341353
def new_subscriber(sender, receiver, action_id):
342354
"""
@@ -349,7 +361,7 @@ def new_subscriber(sender, receiver, action_id):
349361
subscription_line = ""
350362
if target_shake.type == 'group':
351363
subscription_line = " called '%s'" % (target_shake.name)
352-
364+
353365
n = Notification(sender_id=sender.id, receiver_id=receiver.id, action_id=action_id, type='subscriber')
354366

355367
text_message = """Hi, %s.
@@ -381,7 +393,7 @@ def new_subscriber(sender, receiver, action_id):
381393
options.app_host)
382394

383395
n.save()
384-
396+
385397
if not receiver.disable_notifications and not options.debug:
386398
pm = postmark.PMMail(api_key=options.postmark_api_key,
387399
sender="hello@mltshp.com", to=receiver.email,
@@ -390,7 +402,7 @@ def new_subscriber(sender, receiver, action_id):
390402
html_body=html_message)
391403
pm.send()
392404
return n
393-
405+
394406
@staticmethod
395407
def send_shake_member_removal(former_shake, former_member):
396408
"""

static/css/main.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

static/js/main.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,4 +2157,35 @@ $(document).ready(function () {
21572157
alertVote.css({ display: "none" });
21582158
});
21592159
}
2160+
2161+
// Support for sticky site header
2162+
const $siteHeader = $('.site-header');
2163+
if ($siteHeader.length > 0) {
2164+
let lastScrollY = window.scrollY;
2165+
const scrollHandler = () => {
2166+
if (!$siteHeader.hasClass('docked')) {
2167+
if (window.scrollY > 120) {
2168+
$siteHeader.addClass('docked');
2169+
}
2170+
} else {
2171+
if (window.scrollY <= 120) {
2172+
$siteHeader.removeClass('docked visible hidden');
2173+
}
2174+
}
2175+
if ($siteHeader.hasClass('docked')) {
2176+
const isVisible = $siteHeader.hasClass('visible');
2177+
if (!isVisible && window.scrollY < lastScrollY) {
2178+
// triggering delta can be 1px
2179+
$siteHeader.addClass('visible');
2180+
$siteHeader.removeClass('hidden');
2181+
} else if (isVisible && window.scrollY > lastScrollY + 20) {
2182+
// triggering delta must be ~20px
2183+
$siteHeader.removeClass('visible');
2184+
$siteHeader.addClass('hidden');
2185+
}
2186+
}
2187+
lastScrollY = window.scrollY;
2188+
};
2189+
$(window).on('scroll', scrollHandler);
2190+
}
21602191
});

templates/base.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,11 @@
8484
<div class="wrapper">
8585
<header class="site-header">
8686
<div class="site-branding">
87-
<a href="/"><img class="site-branding--logo" src="{{ static_url("images/logo-compact.svg") }}" alt="MLTSHP"></a>
87+
<a href="/"><img class="site-branding--logo" src="{{ static_url("images/logo-compact.svg") }}" alt="MLTSHP">
88+
<span class="site-branding--icon" /></a>
8889
</div>
8990
<nav id="site-nav" class="site-nav">
91+
{% block notification_button %}{% end %}
9092
<button type="button" class="site-nav--toggle btn btn-warning btn-pastel btn-icon">&#9776;</button>
9193
<ul class="site-nav--list">
9294
{% if current_user and current_user_object.is_member() %}

templates/home/index.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
Friend Shake
66
{% end %}
77

8+
{% block notification_button %}
9+
{% if notifications_count > 0 %}
10+
<a href="#notifications-anchor" class="site-nav--notifications btn btn-danger btn-pastel">{{ notifications_count }}</a>
11+
{% end %}
12+
{% end %}
13+
814
{% block main %}
915
<div class="content content-with-sidebar content-account">
1016
<div class="account-header">
@@ -19,7 +25,7 @@ <h2 class="avatar-title">Your Friends</h2>
1925
{% end %}
2026
</div>
2127
</div>
22-
<div class="sidebar">
28+
<div class="sidebar" id="notifications-anchor">
2329
{% if current_user_obj.show_stats %}
2430
{{modules.UserCounts(user=current_user_obj)}}
2531
{% end %}

templates/incoming/index.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22

33
{% block title %}Incoming!!!{% end %}
44

5+
{% block notification_button %}
6+
{% if notifications_count > 0 %}
7+
<a href="#notifications-anchor" class="site-nav--notifications btn btn-danger btn-pastel">{{ notifications_count }}</a>
8+
{% end %}
9+
{% end %}
10+
511
{% block main %}
612
<div class="content content-with-sidebar content-incoming">
713
<div class="incoming-header">
814
<h2 class="incoming-header--title">Our most recent files</h2>
915
</div>
1016

11-
<div class="sidebar">
17+
<div class="sidebar" id="notifications-anchor">
18+
1219
{% if notifications_count > 0 %}
1320
<div class="notification-block notification-block-aggregate" id="notification-block-aggregate">
1421
<div class="notification-block-hd">

templates/popular/index.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44
30 Recently Popular Files
55
{% end %}
66

7+
{% block notification_button %}
8+
{% if notifications_count > 0 %}
9+
<a href="#notifications-anchor" class="site-nav--notifications btn btn-danger btn-pastel">{{ notifications_count }}</a>
10+
{% end %}
11+
{% end %}
12+
713
{% block main %}
814
<div class="content content-with-sidebar content-account">
915
<div class="account-header">
1016
<div class="avatar">
1117
<h2>30 Recently Popular Files</h2>
1218
</div>
1319
</div>
14-
<div class="sidebar">
20+
<div class="sidebar" id="notifications-anchor">
1521
{% if notifications_count > 0 %}
1622
<div class="notification-block notification-block-aggregate" id="notification-block-aggregate">
1723
<div class="notification-block-hd">

0 commit comments

Comments
 (0)