Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,27 @@
|
|||||||
|
app.templates.settingsPage = (settings) -> """
|
||||||
|
<h1 class="_lined-heading">Preferences</h1>
|
||||||
|
|
||||||
|
<div class="_settings-fieldset">
|
||||||
|
<h2 class="_settings-legend">General:</h2>
|
||||||
|
|
||||||
|
<div class="_settings-inputs">
|
||||||
|
<label class="_settings-label">
|
||||||
|
<input type="checkbox" name="dark" value="1"#{if settings.dark then ' checked' else ''}>Enable dark theme
|
||||||
|
</label>
|
||||||
|
<label class="_settings-label _settings-max-width">
|
||||||
|
<input type="checkbox" name="layout" value="_max-width"#{if settings['_max-width'] then ' checked' else ''}>Enable fixed-width layout
|
||||||
|
</label>
|
||||||
|
<label class="_settings-label">
|
||||||
|
<input type="checkbox" name="layout" value="_sidebar-hidden"#{if settings['_sidebar-hidden'] then ' checked' else ''}>Automatically hide and show the sidebar
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="_settings-fieldset">
|
||||||
|
<h2 class="_settings-legend">Advanced:</h2>
|
||||||
|
|
||||||
|
<div class="_settings-inputs">
|
||||||
|
<a href="#" class="_settings-link" data-behavior="reset">Reset all settings and data</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
"""
|
@ -0,0 +1,52 @@
|
|||||||
|
class app.views.SettingsPage extends app.View
|
||||||
|
LAYOUTS = ['_max-width', '_sidebar-hidden']
|
||||||
|
SIDEBAR_HIDDEN_LAYOUT = '_sidebar-hidden'
|
||||||
|
|
||||||
|
@className: '_static'
|
||||||
|
|
||||||
|
@events:
|
||||||
|
change: 'onChange'
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
@html @tmpl('settingsPage', @currentSettings())
|
||||||
|
return
|
||||||
|
|
||||||
|
currentSettings: ->
|
||||||
|
settings = {}
|
||||||
|
settings.dark = app.settings.getDark()
|
||||||
|
settings[layout] = app.settings.hasLayout(layout) for layout in LAYOUTS
|
||||||
|
settings
|
||||||
|
|
||||||
|
getTitle: ->
|
||||||
|
'Preferences'
|
||||||
|
|
||||||
|
toggleDark: (enable) ->
|
||||||
|
css = $('link[rel="stylesheet"][data-alt]')
|
||||||
|
alt = css.getAttribute('data-alt')
|
||||||
|
css.setAttribute('data-alt', css.getAttribute('href'))
|
||||||
|
css.setAttribute('href', alt)
|
||||||
|
app.settings.setDark(enable)
|
||||||
|
app.appCache?.updateInBackground()
|
||||||
|
return
|
||||||
|
|
||||||
|
toggleLayout: (layout, enable) ->
|
||||||
|
app.el.classList[if enable then 'add' else 'remove'](layout) unless layout is SIDEBAR_HIDDEN_LAYOUT
|
||||||
|
app.settings.setLayout(layout, enable)
|
||||||
|
app.appCache?.updateInBackground()
|
||||||
|
return
|
||||||
|
|
||||||
|
onChange: (event) =>
|
||||||
|
input = event.target
|
||||||
|
switch input.name
|
||||||
|
when 'dark'
|
||||||
|
@toggleDark input.checked
|
||||||
|
when 'layout'
|
||||||
|
@toggleLayout input.value, input.checked
|
||||||
|
return
|
||||||
|
|
||||||
|
onRoute: (route) =>
|
||||||
|
if app.isSingleDoc()
|
||||||
|
window.location = "/#/#{route.path}"
|
||||||
|
else
|
||||||
|
@render()
|
||||||
|
return
|
@ -0,0 +1,80 @@
|
|||||||
|
class app.views.Settings extends app.View
|
||||||
|
SIDEBAR_HIDDEN_LAYOUT = '_sidebar-hidden'
|
||||||
|
|
||||||
|
@el: '._settings'
|
||||||
|
|
||||||
|
@elements:
|
||||||
|
sidebar: '._sidebar'
|
||||||
|
saveBtn: 'button[type="submit"]'
|
||||||
|
backBtn: 'button[data-back]'
|
||||||
|
|
||||||
|
@events:
|
||||||
|
submit: 'onSubmit'
|
||||||
|
click: 'onClick'
|
||||||
|
focus: 'onFocus'
|
||||||
|
|
||||||
|
@shortcuts:
|
||||||
|
enter: 'onEnter'
|
||||||
|
|
||||||
|
init: ->
|
||||||
|
@addSubview @docPicker = new app.views.DocPicker
|
||||||
|
return
|
||||||
|
|
||||||
|
activate: ->
|
||||||
|
if super
|
||||||
|
@render()
|
||||||
|
app.el.classList.remove(SIDEBAR_HIDDEN_LAYOUT)
|
||||||
|
app.appCache?.on 'progress', @onAppCacheProgress
|
||||||
|
return
|
||||||
|
|
||||||
|
deactivate: ->
|
||||||
|
if super
|
||||||
|
@resetClass()
|
||||||
|
@docPicker.detach()
|
||||||
|
app.el.classList.add(SIDEBAR_HIDDEN_LAYOUT) if app.settings.hasLayout(SIDEBAR_HIDDEN_LAYOUT)
|
||||||
|
app.appCache?.off 'progress', @onAppCacheProgress
|
||||||
|
return
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
@docPicker.appendTo @sidebar
|
||||||
|
@refreshElements()
|
||||||
|
@addClass '_in'
|
||||||
|
return
|
||||||
|
|
||||||
|
save: ->
|
||||||
|
unless @saving
|
||||||
|
@saving = true
|
||||||
|
docs = @docPicker.getSelectedDocs()
|
||||||
|
app.settings.setDocs(docs)
|
||||||
|
@saveBtn.textContent = if app.appCache then 'Downloading\u2026' else 'Saving\u2026'
|
||||||
|
disabledDocs = new app.collections.Docs(doc for doc in app.docs.all() when docs.indexOf(doc.slug) is -1)
|
||||||
|
disabledDocs.uninstall ->
|
||||||
|
app.db.migrate()
|
||||||
|
app.reload()
|
||||||
|
return
|
||||||
|
|
||||||
|
onEnter: =>
|
||||||
|
@save()
|
||||||
|
return
|
||||||
|
|
||||||
|
onSubmit: (event) =>
|
||||||
|
event.preventDefault()
|
||||||
|
@save()
|
||||||
|
return
|
||||||
|
|
||||||
|
onClick: (event) =>
|
||||||
|
return if event.which isnt 1
|
||||||
|
if event.target is @backBtn
|
||||||
|
$.stopEvent(event)
|
||||||
|
app.router.show '/'
|
||||||
|
return
|
||||||
|
|
||||||
|
onFocus: (event) =>
|
||||||
|
$.scrollTo event.target, @el, 'continuous', bottomGap: 2
|
||||||
|
return
|
||||||
|
|
||||||
|
onAppCacheProgress: (event) =>
|
||||||
|
if event.lengthComputable
|
||||||
|
percentage = Math.round event.loaded * 100 / event.total
|
||||||
|
@saveBtn.textContent = "Downloading\u2026 (#{percentage}%)"
|
||||||
|
return
|
@ -0,0 +1,146 @@
|
|||||||
|
//
|
||||||
|
// Settings
|
||||||
|
//
|
||||||
|
|
||||||
|
._settings {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: $headerZ;
|
||||||
|
|
||||||
|
&._in { display: block; }
|
||||||
|
|
||||||
|
._sidebar {
|
||||||
|
bottom: $headerHeight;
|
||||||
|
|
||||||
|
._sidebar-hidden & { display: block; }
|
||||||
|
}
|
||||||
|
|
||||||
|
._header {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
._settings-fieldset {
|
||||||
|
display: flex;
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
._settings-legend {
|
||||||
|
flex: 0 1 10rem;
|
||||||
|
margin: 0;
|
||||||
|
padding-right: .5rem;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: $boldFontWeight;
|
||||||
|
text-align: right;
|
||||||
|
@extend %border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
._settings-inputs {
|
||||||
|
flex: 1 1 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
._settings-label {
|
||||||
|
margin: 0 0 .375rem;
|
||||||
|
|
||||||
|
> small {
|
||||||
|
display: block;
|
||||||
|
color: $textColorLight;
|
||||||
|
margin-left: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox] {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
margin: .25rem .375rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $maxWidth) {
|
||||||
|
._settings-max-width { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
._settings-link {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-left: .375rem;
|
||||||
|
|
||||||
|
&[data-behavior=reset] {
|
||||||
|
font-size: .75rem;
|
||||||
|
color: $textColorRed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
._footer {
|
||||||
|
position: absolute;
|
||||||
|
z-index: $headerZ;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: $sidebarWidth;
|
||||||
|
height: $headerHeight;
|
||||||
|
background: $noteGreenBackground;
|
||||||
|
border-top: 1px solid $noteGreenBorder;
|
||||||
|
border-right: 1px solid $noteGreenBorder;
|
||||||
|
@extend %border-box;
|
||||||
|
@extend %user-select-none;
|
||||||
|
|
||||||
|
@media #{$mediumScreen} { width: $sidebarMediumWidth; }
|
||||||
|
}
|
||||||
|
|
||||||
|
._settings-btn {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
padding: 0 .75rem;
|
||||||
|
font-size: .875rem;
|
||||||
|
font-weight: $boldFontWeight;
|
||||||
|
color: inherit;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
@extend %border-box;
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
margin-right: .125rem;
|
||||||
|
fill: currentColor;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
._save-btn { width: 100%; }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Header tabs
|
||||||
|
//
|
||||||
|
|
||||||
|
._settings-tabs {
|
||||||
|
display: none; // mobile only
|
||||||
|
margin-right: .5rem;
|
||||||
|
line-height: $headerHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
._settings-tab {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0 .75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&, &:hover {
|
||||||
|
color: $textColorLight;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $textColor;
|
||||||
|
font-weight: $boldFontWeight;
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: inset 0 -2px $linkColor;
|
||||||
|
}
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
http://happytodesign.com/hicons/
|
|
Before Width: | Height: | Size: 119 B |
Before Width: | Height: | Size: 158 B |
@ -1 +0,0 @@
|
|||||||
http://happytodesign.com/hicons/
|
|
Before Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 206 B |
Before Width: | Height: | Size: 177 B |
Before Width: | Height: | Size: 378 B |
Before Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 390 B |
@ -1 +0,0 @@
|
|||||||
http://www.entypo.com/
|
|
Before Width: | Height: | Size: 262 B |
Before Width: | Height: | Size: 522 B |
@ -1 +0,0 @@
|
|||||||
http://www.entypo.com/
|
|
Before Width: | Height: | Size: 244 B |
Before Width: | Height: | Size: 495 B |
@ -1 +0,0 @@
|
|||||||
http://gemicon.net/
|
|
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 399 B |
@ -1 +0,0 @@
|
|||||||
http://gemicon.net/
|
|
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.3 KiB |
@ -1,2 +1,2 @@
|
|||||||
User-agent: *
|
User-agent: *
|
||||||
Allow: /
|
Disallow: /settings
|