Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge popup UI update #48

Merged
merged 26 commits into from
Oct 19, 2018
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b82a635
update some dependencies
noloerino Aug 17, 2018
636d560
added multiple messages w/o cosmetic changes
noloerino Aug 17, 2018
284fb02
ignore .swp
noloerino Aug 17, 2018
b5d0929
Merge branch 'master' of https://github.com/nicolaschan/bell into ts
noloerino Aug 17, 2018
a1783a2
added collapse/expand, pending tests/css
noloerino Aug 17, 2018
c521f57
changed countdown.zone link to bell.plus
noloerino Aug 18, 2018
32ec05e
Add css for notification collapse
noloerino Aug 18, 2018
b38a168
Merge branch 'dev' into ts
noloerino Aug 18, 2018
a22a23d
Merge pull request #44 from nicolaschan/ts
nicolaschan Aug 18, 2018
12a2f86
removed collapse td for only one message
noloerino Aug 20, 2018
9298d6f
remove /api/time
noloerino Aug 22, 2018
917e6f3
added cap on popup storage
noloerino Aug 27, 2018
a3b93c2
Merge branch 'dev' of ssh://github.com/nicolaschan/bell into dev
nicolaschan Aug 27, 2018
1b272b2
Merge branch 'master' of ssh://github.com/nicolaschan/bell into dev
nicolaschan Aug 27, 2018
873478c
v4.2.0
nicolaschan Aug 27, 2018
890e3c3
Switch to mithril-selector
nicolaschan Oct 12, 2018
63c03a6
Add sticker images
nicolaschan Oct 12, 2018
e060bf9
Fix analytics reporting race condition
nicolaschan Oct 12, 2018
006203a
Fix style
nicolaschan Oct 12, 2018
572fd18
Alphabetize keys
nicolaschan Oct 12, 2018
e1d0565
Update README links
nicolaschan Oct 19, 2018
a825ed8
Update mithril-selector
nicolaschan Oct 19, 2018
1e72d33
v4.4.0
nicolaschan Oct 19, 2018
22cf960
Use default theme for settings if no cookie
nicolaschan Oct 19, 2018
795eea1
Make Halloween automatically expire
nicolaschan Oct 19, 2018
7286538
Pass tests and fix style
nicolaschan Oct 19, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ id.txt
# Because Jonathan uses a mac
.DS_Store

# for vim
.swp

# Chrome app zip
bellxt.zip

Expand Down
11 changes: 8 additions & 3 deletions css/style-mithril.css
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,19 @@ select:focus {
margin-bottom: 0.3em;
font-size: 1em;
}
.dismiss {
.collapse-icon {
margin-top: 0.1em;
margin-bottom: 0.1em;
font-size: 1.4em;
}
.dismiss, .collapse {
font-size: 1em;
}
.dismiss:link, .dismiss:visited {
.dismiss:link, .dismiss:visited, .collapse:link, .collapse:visited {
color: #aaaaaa;
transition: color 0.5s ease;
}
.dismiss:hover {
.dismiss:hover, .collapse:hover {
color: red;
}

Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bell-countdown",
"version": "4.1.0",
"version": "4.2.0",
"description": "Countdown to the next time the bell rings at school.",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -65,15 +65,15 @@
"babel-preset-env": "^1.6.1",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"codecov": "^3.0.0",
"codecov": "^3.0.4",
"coffee-loader": "^0.9.0",
"coffeescript": "^2.0.1",
"eslint-plugin-typescript": "^0.12.0",
"istanbul": "^0.4.5",
"istanbul-instrumenter-loader": "^3.0.0",
"karma": "^2.0.0",
"karma": "^3.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.1",
"karma-coverage": "^1.1.2",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-firefox-launcher": "^1.0.1",
"karma-mocha": "^1.3.0",
Expand All @@ -88,7 +88,7 @@
"typescript-eslint-parser": "^18.0.0",
"uglifyjs-webpack-plugin": "^1.0.1",
"webpack": "^4.1.0",
"webpack-cli": "^2.0.10",
"webpack-cli": "^3.1.0",
"webpack-dev-middleware": "^3.0.0",
"webpack-merge": "^4.1.2"
}
Expand Down
5 changes: 0 additions & 5 deletions server/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ router.get('/uuid', (req, res) => {
id: shortid.generate()
})
})
router.get('/time', (req, res) => {
res.json({
time: Date.now()
})
})
router.get('/error', (req, res) => {
res.status(400).send('Bad request')
})
Expand Down
4 changes: 2 additions & 2 deletions server/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ const alertAboutVersionChange = function (localVersion, remoteVersion) {

if (comparison > 0) {
// Local version is greater than the remote version
logger.info(`This is future version bell-countdown@${localVersion} (countdown.zone is ${remoteVersion})`)
logger.info(`This is future version bell-countdown@${localVersion} (bell.plus is ${remoteVersion})`)
} else if (comparison < 0) {
// Local version is less than the remote version
logger.warn('There is a new version of bell-countdown available')
logger.warn(`You are using ${localVersion} while the newest version available is ${remoteVersion}`)
logger.warn('Please update by visiting https://countdown.zone/gh')
logger.warn('Please update by visiting https://bell.plus/gh')
} else {
// Local version matches remote version
logger.info(`bell-countdown@${localVersion} is up to date`)
Expand Down
79 changes: 58 additions & 21 deletions src/PopupModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,77 @@ const deepCompare = (obj1: any, obj2: any) => {

export default class PopupModel extends Refresher {

get visible () {
return this.enabled && this.text && this.text !== cookieManager.get('popup')
}

set visible (visible) {
if (visible) {
cookieManager.remove('popup').catch((e) => { /* not much we can do */ })
} else {
cookieManager.set('popup', this.text).catch((e) => { /* not much we can do */ })
/**
* Returns a list of all messages that should be visible to the user, including both text
* and an optional href.
*/
get messages () {
const content = cookieManager.get('popup', [])
const keys = Object.keys(this.msgs)
if (typeof content === 'string') {
// convert from legacy, where only one message was seen at a given time
cookieManager.set('popup', [content]).catch((e) => { /* not much we can do */ })
return keys.filter((text) => text !== content)
.map((text) => ({ text, href: this.msgs[text] }))
}
if (Array.isArray(content)) {
// don't show messages that have already been hidden
return keys.filter((text) => content.indexOf(text) < 0)
.map((text) => ({ text, href: this.msgs[text] }))
}
return {}
}
public text: string
public href?: string
private msgs: { [text: string]: string }
private source: string
private enabled: boolean

constructor (source: string) {
super(1 * 60 * 1000)
this.source = source
this.enabled = false
this.text = ''
this.msgs = {}
}

/**
* Specifies that the given popup message should be invisible.
* Note that the cookie only stores text, not the href.
*/
public markAsRead (text: string, read: boolean) {
const readMsgs = cookieManager.get('popup', [])
// mark as unread, not sure if we'd ever need this though
if (!read) {
if (typeof readMsgs === 'string') {
if (readMsgs === text) {
cookieManager.remove('popup').catch((e) => { /* not much we can do */ })
}
} else {
const ind = readMsgs.indexOf(text)
if (ind > 0) {
readMsgs.splice(ind, 1)
}
cookieManager.set('popup', readMsgs).catch((e) => { /* not much we can do */ })
}
} else {
if (typeof readMsgs === 'string') {
const arr = text === readMsgs ? [readMsgs] : [readMsgs, text]
cookieManager.set('popup', arr).catch((e) => { /* not much we can do */ })
} else {
if (readMsgs.indexOf(text) < 0) {
readMsgs.push(text)
// limit storage to 10 messages
cookieManager.set('popup', readMsgs.slice(-10)).catch((e) => { /* not much we can do */ })
}
}
}
}

public async reloadData () {
const messages = await requestManager.get(`/api/data/${this.source}/message`, [])
const ua = new UAParser(navigator.userAgent)

// using 'new' returns the wrong result -- be careful
// @ts-ignore:2348
const ua = UAParser(navigator.userAgent)
for (const message of messages) {
const matches = !message.agent || deepCompare(ua, message.agent)
const matches = !message.agent || (deepCompare(ua, message.agent) && message.message.enabled)
if (matches) {
this.enabled = message.message.enabled
this.text = message.message.text.trim()
this.href = message.message.href
break
this.msgs[message.message.text.trim()] = message.message.href
}
}
}
Expand Down
56 changes: 42 additions & 14 deletions src/ui/Popup.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,60 @@
const m = require('mithril')
const PopupModel = require('../PopupModel').default

var dismiss = (pm, text) => m('td', m('a.dismiss.center-vertical[href=javascript:void(0)]', {
title: 'Dismiss',
onclick: function () {
pm.markAsRead(text, true)
}
}, m('i.dismiss-icon.material-icons', 'cancel')))

var collapseOrShow = (visible) => visible
? m('td', m(`a.collapse.center-vertical[href=javascript:void(0)]`, {
title: expanded ? 'Show less' : 'Show more',
onclick: function () {
expanded = !expanded
}
}, m(`i.collapse-icon.material-icons`, expanded ? 'expand_less' : 'expand_more')))
: m('span')

var expanded = false

var Popup = {
oninit: function (vnode) {
vnode.attrs.popupModel = new PopupModel(vnode.attrs.source)
vnode.attrs.popupModel.initialize()
},
view: function (vnode) {
if (!vnode.attrs.popupModel.visible) { return }
const messages = vnode.attrs.popupModel.messages
if (!messages || messages.length === 0) { return }
var bellTimer = vnode.attrs.bellTimer
var theme = vnode.attrs.themeManager.currentTheme.theme(bellTimer)

var row1 = [m('tr', [
m('td', m(`${messages[0].href ? 'a.link' : 'span'}.center-vertical[target=_blank]`, {
href: messages[0].href,
style: theme.subtext
}, messages[0].text)),
collapseOrShow(messages.length > 1),
dismiss(vnode.attrs.popupModel, messages[0].text)
])]
var makeRows = () => (
// not sure if iteration order is guaranteed, but oh well
// take up to 5 notifications to avoid clutter
expanded ? messages.slice(1, 5).map((msg) => m('tr', [
m('td', m(`${msg.href ? 'a.link' : 'span'}.center-vertical[target=_blank]`, {
href: messages.href,
style: theme.subtext
}, msg.text)),
m('td'), // empty to accomodate first row's collapse button
dismiss(vnode.attrs.popupModel, msg.text)
])) : [])
return m('span', {
style: {
visibility: (vnode.attrs.popupModel.visible) ? 'visible' : 'hidden' }
visibility: messages && messages.length > 0 ? 'visible' : 'hidden' }
}, m('.top.right.popup.fade-in', {
style: theme.contrast
}, m('table', m('tr', [
m('td', m(`${vnode.attrs.popupModel.href ? 'a.link' : 'span'}.center-vertical[target=_blank]`, {
href: vnode.attrs.popupModel.href,
style: theme.subtext
}, vnode.attrs.popupModel.text)),
m('td', m('a.dismiss.center-vertical[href=javascript:void(0)]', {
onclick: function () {
vnode.attrs.popupModel.visible = false
}
}, m('i.dismiss-icon.material-icons', 'cancel')))
]))))
}, m('table', row1.concat(makeRows()))
))
},
onremove: function (vnode) {
vnode.attrs.popupModel.stopRefreshing()
Expand Down
2 changes: 1 addition & 1 deletion src/ui/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const Settings = {
}
}, m('i.done-icon.icon.material-icons', 'done'))),
m('.footer-left[style=position: fixed;]', [m('a[style=margin-right: 2em;]', {
href: 'https://countdown.zone/about'
href: 'https://bell.plus/about'
}, 'About'),
m('a', {
href: '/xt'
Expand Down