diff --git a/assets/images/icons.png b/assets/images/icons.png
index c2cb28aa..70038ca5 100644
Binary files a/assets/images/icons.png and b/assets/images/icons.png differ
diff --git a/assets/images/icons@2x.png b/assets/images/icons@2x.png
index 3b370af0..43838d4d 100644
Binary files a/assets/images/icons@2x.png and b/assets/images/icons@2x.png differ
diff --git a/assets/javascripts/app/appcache.coffee b/assets/javascripts/app/appcache.coffee
index d79af1ea..3761c524 100644
--- a/assets/javascripts/app/appcache.coffee
+++ b/assets/javascripts/app/appcache.coffee
@@ -16,21 +16,26 @@ class app.AppCache
update: ->
@notifyUpdate = true
+ @notifyProgress = true
try @cache.update() catch
return
updateInBackground: ->
@notifyUpdate = false
+ @notifyProgress = false
try @cache.update() catch
return
reload: ->
$.on @cache, 'updateready noupdate error', -> window.location = '/'
@updateInBackground()
+ @notifyUpdate = false
+ @notifyProgress = true
+ @cache.update()
return
onProgress: (event) =>
- @trigger 'progress', event
+ @trigger 'progress', event if @notifyProgress
return
onUpdateReady: =>
diff --git a/assets/javascripts/app/router.coffee b/assets/javascripts/app/router.coffee
index 02b0babc..91b2cfef 100644
--- a/assets/javascripts/app/router.coffee
+++ b/assets/javascripts/app/router.coffee
@@ -2,16 +2,17 @@ class app.Router
$.extend @prototype, Events
@routes: [
- ['*', 'before' ]
- ['/', 'root' ]
- ['/offline', 'offline' ]
- ['/about', 'about' ]
- ['/news', 'news' ]
- ['/help', 'help' ]
- ['/:doc-:type/', 'type' ]
- ['/:doc/', 'doc' ]
- ['/:doc/:path(*)', 'entry' ]
- ['*', 'notFound']
+ ['*', 'before' ]
+ ['/', 'root' ]
+ ['/settings', 'settings' ]
+ ['/offline', 'offline' ]
+ ['/about', 'about' ]
+ ['/news', 'news' ]
+ ['/help', 'help' ]
+ ['/:doc-:type/', 'type' ]
+ ['/:doc/', 'doc' ]
+ ['/:doc/:path(*)', 'entry' ]
+ ['*', 'notFound' ]
]
constructor: ->
@@ -76,6 +77,10 @@ class app.Router
@triggerRoute 'root'
return
+ settings: ->
+ @triggerRoute 'settings'
+ return
+
offline: ->
@triggerRoute 'offline'
return
diff --git a/assets/javascripts/app/settings.coffee b/assets/javascripts/app/settings.coffee
index a2aad287..96f923bd 100644
--- a/assets/javascripts/app/settings.coffee
+++ b/assets/javascripts/app/settings.coffee
@@ -57,6 +57,9 @@ class app.Settings
@store.set DARK_KEY, !!value
return
+ getDark: ->
+ @store.get DARK_KEY
+
setLayout: (name, enable) ->
layout = (@store.get(LAYOUT_KEY) || '').split(' ')
$.arrayDelete(layout, '')
diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json
index 01974bf8..a67185d7 100644
--- a/assets/javascripts/news.json
+++ b/assets/javascripts/news.json
@@ -64,7 +64,7 @@
"New documentations: Erlang and Tcl/Tk"
], [
"2016-01-24",
- "“Multi-version support” has landed!\nClick Select documentation to pick which versions to use. More versions will be added in the coming weeks.\nIf you notice any bugs, please report them on GitHub."
+ "“Multi-version support” has landed!"
], [
"2015-11-22",
"New documentations: Phoenix, Dojo, Relay and Flow"
@@ -117,10 +117,10 @@
"New io.js, Symfony, Clojure, Lua and Yii 1.1 documentations"
], [
"2015-02-08",
- "New dark theme\nClick the icon in the bottom left corner to activate.\nFeedback welcome :)"
+ "New dark theme"
], [
"2015-01-13",
- "Offline mode has landed!\nIf you notice any bugs, please report them on GitHub."
+ "Offline mode has landed!"
], [
"2014-12-21",
"New React, RethinkDB, Socket.IO, Modernizr and Bower documentations"
diff --git a/assets/javascripts/templates/notice_tmpl.coffee b/assets/javascripts/templates/notice_tmpl.coffee
index 6aab2e42..75818967 100644
--- a/assets/javascripts/templates/notice_tmpl.coffee
+++ b/assets/javascripts/templates/notice_tmpl.coffee
@@ -6,4 +6,4 @@ app.templates.singleDocNotice = (doc) ->
app.templates.disabledDocNotice = ->
notice """ This documentation is disabled.
- To enable it, click Select documentation. """
+ To enable it, go to Preferences. """
diff --git a/assets/javascripts/templates/notif_tmpl.coffee b/assets/javascripts/templates/notif_tmpl.coffee
index 73a3352c..38c36305 100644
--- a/assets/javascripts/templates/notif_tmpl.coffee
+++ b/assets/javascripts/templates/notif_tmpl.coffee
@@ -47,7 +47,7 @@ app.templates.notifUpdates = (docs, disabledDocs) ->
for doc in disabledDocs
html += "
#{doc.name}"
html += " →
#{doc.release}" if doc.release
- html += """Enable"""
+ html += """Enable"""
html += ''
notif 'Updates', "#{html}"
diff --git a/assets/javascripts/templates/pages/offline_tmpl.coffee b/assets/javascripts/templates/pages/offline_tmpl.coffee
index b6ba31c1..d60d9968 100644
--- a/assets/javascripts/templates/pages/offline_tmpl.coffee
+++ b/assets/javascripts/templates/pages/offline_tmpl.coffee
@@ -35,7 +35,7 @@ app.templates.offlinePage = (docs) -> """
How do I uninstall/reset the app?
Click here.
Why aren't all documentations listed above?
- You have to enable them first.
+ You have to enable them first.
"""
diff --git a/assets/javascripts/templates/pages/root_tmpl.coffee.erb b/assets/javascripts/templates/pages/root_tmpl.coffee.erb
index a2420487..e7050bd2 100644
--- a/assets/javascripts/templates/pages/root_tmpl.coffee.erb
+++ b/assets/javascripts/templates/pages/root_tmpl.coffee.erb
@@ -32,14 +32,14 @@ app.templates.intro = """
DevDocs combines multiple API documentations in a fast, organized, and searchable interface.
Here's what you should know before you start:
- - To enable more docs, click Select documentation in the bottom left corner
-
- You don't have to use your mouse — see the list of keyboard shortcuts
-
- The search supports fuzzy matching (e.g. "bgcp" brings up "background-clip")
-
- To search a specific documentation, type its name (or an abbreviation), then Tab
-
- You can search using your browser's address bar — learn how
+
- Open the Preferences to enable more docs and customize the UI.
+
- You don't have to use your mouse — see the list of keyboard shortcuts.
+
- The search supports fuzzy matching (e.g. "bgcp" brings up "background-clip").
+
- To search a specific documentation, type its name (or an abbr.), then Tab.
+
- You can search using your browser's address bar — learn how.
- DevDocs works offline, on mobile, and can be installed on Chrome.
-
- For the latest news, follow @DevDocs
-
- DevDocs is free and open source
+
- For the latest news, follow @DevDocs.
+
- DevDocs is free and open source.
- If you like the app, please consider supporting the project on Gratipay. Thanks!
@@ -54,11 +54,11 @@ app.templates.mobileIntro = """
DevDocs combines multiple API documentations in a fast, organized, and searchable interface.
Here's what you should know before you start:
- - To pick your docs, click Select documentation at the bottom of the menu
-
- The search supports fuzzy matching (e.g. "bgcp" matches "background-clip")
-
- To search a specific documentation, type its name (or an abbreviation), then Space
-
- For the latest news, follow @DevDocs
-
- DevDocs is open source
+
- Pick your docs in the Preferences.
+
- The search supports fuzzy matching.
+
- To search a specific documentation, type its name (or an abbr.), then Space.
+
- For the latest news, follow @DevDocs.
+
- DevDocs is open source.
Happy coding!
Stop showing this message
diff --git a/assets/javascripts/templates/pages/settings_tmpl.coffee b/assets/javascripts/templates/pages/settings_tmpl.coffee
new file mode 100644
index 00000000..31cc0e72
--- /dev/null
+++ b/assets/javascripts/templates/pages/settings_tmpl.coffee
@@ -0,0 +1,27 @@
+app.templates.settingsPage = (settings) -> """
+
Preferences
+
+
+
+
+"""
diff --git a/assets/javascripts/templates/sidebar_tmpl.coffee b/assets/javascripts/templates/sidebar_tmpl.coffee
index f37dabcc..bb5dc623 100644
--- a/assets/javascripts/templates/sidebar_tmpl.coffee
+++ b/assets/javascripts/templates/sidebar_tmpl.coffee
@@ -30,7 +30,7 @@ templates.sidebarResult = (entry) ->
templates.sidebarNoResults = ->
html = """ No results.
"""
html += """
- Note: documentations must be
enabled to appear in the search.
+ Note: documentations must be
enabled to appear in the search.
""" unless app.isSingleDoc() or app.disabledDocs.isEmpty()
html
@@ -58,19 +58,7 @@ templates.sidebarDisabledList = (html) ->
templates.sidebarDisabledVersionedDoc = (doc, versions) ->
"""#{doc.name}#{versions}
"""
-templates.sidebarPickerNote = """
+templates.docPickerNote = """
Tip: for faster and better search results, select only the docs you need.
Vote for new documentation
"""
-
-sidebarFooter = (html) -> """"""
-
-templates.sidebarSettings = ->
- sidebarFooter """
-
-
-
- """
-
-templates.sidebarSave = ->
- sidebarFooter """"""
diff --git a/assets/javascripts/views/content/content.coffee b/assets/javascripts/views/content/content.coffee
index 40079423..404938b4 100644
--- a/assets/javascripts/views/content/content.coffee
+++ b/assets/javascripts/views/content/content.coffee
@@ -23,11 +23,12 @@ class app.views.Content extends app.View
@scrollMap = {}
@scrollStack = []
- @rootPage = new app.views.RootPage
- @staticPage = new app.views.StaticPage
- @offlinePage = new app.views.OfflinePage
- @typePage = new app.views.TypePage
- @entryPage = new app.views.EntryPage
+ @rootPage = new app.views.RootPage
+ @staticPage = new app.views.StaticPage
+ @settingsPage = new app.views.SettingsPage
+ @offlinePage = new app.views.OfflinePage
+ @typePage = new app.views.TypePage
+ @entryPage = new app.views.EntryPage
@entryPage
.on 'loading', @onEntryLoading
@@ -148,6 +149,8 @@ class app.views.Content extends app.View
@show @entryPage
when 'type'
@show @typePage
+ when 'settings'
+ @show @settingsPage
when 'offline'
@show @offlinePage
else
diff --git a/assets/javascripts/views/content/settings_page.coffee b/assets/javascripts/views/content/settings_page.coffee
new file mode 100644
index 00000000..7b74e6bf
--- /dev/null
+++ b/assets/javascripts/views/content/settings_page.coffee
@@ -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
diff --git a/assets/javascripts/views/layout/document.coffee b/assets/javascripts/views/layout/document.coffee
index 9ec83fd7..6cc507dc 100644
--- a/assets/javascripts/views/layout/document.coffee
+++ b/assets/javascripts/views/layout/document.coffee
@@ -1,7 +1,4 @@
class app.views.Document extends app.View
- MAX_WIDTH_LAYOUT = '_max-width'
- SIDEBAR_HIDDEN_LAYOUT = '_sidebar-hidden'
-
@el: document
@events:
@@ -13,44 +10,32 @@ class app.views.Document extends app.View
superLeft: 'onBack'
superRight: 'onForward'
+ @routes:
+ after: 'afterRoute'
+
init: ->
@addSubview @menu = new app.views.Menu,
@addSubview @sidebar = new app.views.Sidebar
@addSubview @resizer = new app.views.Resizer if app.views.Resizer.isSupported()
@addSubview @content = new app.views.Content
@addSubview @path = new app.views.Path unless app.isSingleDoc() or app.isMobile()
+ @settings = new app.views.Settings unless app.isSingleDoc()
$.on document.body, 'click', @onClick
@activate()
return
- toggleLight: ->
- 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(alt.indexOf('dark') > 0)
- app.appCache?.updateInBackground()
- return
-
- toggleLayout: ->
- wantsMaxWidth = !app.el.classList.contains(MAX_WIDTH_LAYOUT)
- app.el.classList[if wantsMaxWidth then 'add' else 'remove'](MAX_WIDTH_LAYOUT)
- app.settings.setLayout(MAX_WIDTH_LAYOUT, wantsMaxWidth)
- app.appCache?.updateInBackground()
- return
-
- toggleSidebarLayout: ->
- shouldHide = !app.settings.hasLayout(SIDEBAR_HIDDEN_LAYOUT)
- app.el.classList[if shouldHide then 'add' else 'remove'](SIDEBAR_HIDDEN_LAYOUT)
- app.settings.setLayout(SIDEBAR_HIDDEN_LAYOUT, shouldHide)
- app.appCache?.updateInBackground()
- return
-
setTitle: (title) ->
@el.title = if title then "DevDocs — #{title}" else 'DevDocs API Documentation'
+ afterRoute: (route) =>
+ if route is 'settings'
+ @settings?.activate()
+ else
+ @settings?.deactivate()
+ return
+
onVisibilityChange: =>
return unless @el.visibilityState is 'visible'
@delay ->
diff --git a/assets/javascripts/views/layout/mobile.coffee b/assets/javascripts/views/layout/mobile.coffee
index 1774e992..5c3fd60a 100644
--- a/assets/javascripts/views/layout/mobile.coffee
+++ b/assets/javascripts/views/layout/mobile.coffee
@@ -2,9 +2,10 @@ class app.views.Mobile extends app.View
@className: '_mobile'
@elements:
- body: 'body'
- content: '._container'
- sidebar: '._sidebar'
+ body: 'body'
+ content: '._container'
+ sidebar: '._sidebar'
+ docPicker: '._settings ._sidebar'
@routes:
after: 'afterRoute'
@@ -34,7 +35,6 @@ class app.views.Mobile extends app.View
init: ->
FastClick.attach @body
- $.on @body, 'click', @onClick
$.on $('._search'), 'touchend', @onTapSearch
@toggleSidebar = $('button[data-toggle-sidebar]')
@@ -49,6 +49,14 @@ class app.views.Mobile extends app.View
@forward.removeAttribute('hidden')
$.on @forward, 'click', @onClickForward
+ @docPickerTab = $('a[data-tab="doc-picker"]')
+ @docPickerTab.removeAttribute('hidden')
+ $.on @docPickerTab, 'click', @onClickDocPickerTab
+
+ @settingsTab = $('a[data-tab="settings"]')
+ @settingsTab.removeAttribute('hidden')
+ $.on @settingsTab, 'click', @onClickSettingsTab
+
app.document.sidebar.search
.on 'searching', @showSidebar
@@ -82,11 +90,6 @@ class app.views.Mobile extends app.View
isSidebarShown: ->
@sidebar.style.display isnt 'none'
- onClick: (event) =>
- if event.target.hasAttribute 'data-pick-docs'
- @showSidebar()
- return
-
onClickBack: =>
history.back()
@@ -97,12 +100,41 @@ class app.views.Mobile extends app.View
if @isSidebarShown() then @hideSidebar() else @showSidebar()
return
+ onClickDocPickerTab: (event) =>
+ $.stopEvent(event)
+ @showDocPicker()
+ return
+
+ onClickSettingsTab: (event) =>
+ $.stopEvent(event)
+ @showSettings()
+ return
+
+ showDocPicker: ->
+ @docPickerTab.classList.add 'active'
+ @settingsTab.classList.remove 'active'
+ @docPicker.style.display = 'block'
+ @content.style.display = 'none'
+ return
+
+ showSettings: ->
+ @docPickerTab.classList.remove 'active'
+ @settingsTab.classList.add 'active'
+ @docPicker.style.display = 'none'
+ @content.style.display = 'block'
+ return
+
onTapSearch: =>
window.scrollTo 0, 0
- afterRoute: =>
+ afterRoute: (route) =>
@hideSidebar()
+ if route is 'settings'
+ @showDocPicker()
+ else
+ @content.style.display = 'block'
+
if page.canGoBack()
@back.removeAttribute('disabled')
else
diff --git a/assets/javascripts/views/layout/resizer.coffee b/assets/javascripts/views/layout/resizer.coffee
index 5932f5cd..0be82594 100644
--- a/assets/javascripts/views/layout/resizer.coffee
+++ b/assets/javascripts/views/layout/resizer.coffee
@@ -1,12 +1,9 @@
class app.views.Resizer extends app.View
@className: '_resizer'
- @attributes:
- title: 'Click to toggle sidebar on/off'
@events:
dragstart: 'onDragStart'
dragend: 'onDragEnd'
- click: 'onClick'
@isSupported: ->
'ondragstart' of document.createElement('div') and !app.isMobile()
@@ -34,10 +31,6 @@ class app.views.Resizer extends app.View
app.appCache?.updateInBackground()
return
- onClick: ->
- app.document.toggleSidebarLayout()
- return
-
onDragStart: (event) =>
@style.removeAttribute('disabled')
event.dataTransfer.effectAllowed = 'link'
diff --git a/assets/javascripts/views/layout/settings.coffee b/assets/javascripts/views/layout/settings.coffee
new file mode 100644
index 00000000..d669f002
--- /dev/null
+++ b/assets/javascripts/views/layout/settings.coffee
@@ -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
diff --git a/assets/javascripts/views/search/search.coffee b/assets/javascripts/views/search/search.coffee
index dc41c876..8d0032f3 100644
--- a/assets/javascripts/views/search/search.coffee
+++ b/assets/javascripts/views/search/search.coffee
@@ -51,14 +51,6 @@ class app.views.Search extends app.View
@autoFocus()
return
- disable: ->
- @input.setAttribute('disabled', 'disabled')
- return
-
- enable: ->
- @input.removeAttribute('disabled')
- return
-
onReady: =>
@value = ''
@delay @onInput
diff --git a/assets/javascripts/views/sidebar/doc_picker.coffee b/assets/javascripts/views/sidebar/doc_picker.coffee
index 98a8421f..b0869aec 100644
--- a/assets/javascripts/views/sidebar/doc_picker.coffee
+++ b/assets/javascripts/views/sidebar/doc_picker.coffee
@@ -1,18 +1,9 @@
class app.views.DocPicker extends app.View
@className: '_list _list-picker'
- @attributes:
- role: 'form'
-
- @elements:
- saveLink: '._sidebar-footer-save'
@events:
- click: 'onClick'
mousedown: 'onMouseDown'
- @shortcuts:
- enter: 'onEnter'
-
init: ->
@addSubview @listFold = new app.views.ListFold(@el)
return
@@ -20,14 +11,12 @@ class app.views.DocPicker extends app.View
activate: ->
if super
@render()
- app.appCache?.on 'progress', @onAppCacheProgress
$.on @el, 'focus', @onDOMFocus, true
return
deactivate: ->
if super
@empty()
- app.appCache?.off 'progress', @onAppCacheProgress
$.off @el, 'focus', @onDOMFocus, true
@focusEl = null
return
@@ -43,8 +32,7 @@ class app.views.DocPicker extends app.View
else
html += @tmpl('sidebarLabel', doc, checked: app.docs.contains(doc))
- @html html + @tmpl('sidebarPickerNote') + @tmpl('sidebarSave')
- @refreshElements()
+ @html html + @tmpl('docPickerNote')
$.requestAnimationFrame =>
@addClass '_in'
@@ -68,31 +56,13 @@ class app.views.DocPicker extends app.View
super
return
- save: ->
- unless @saving
- @saving = true
- docs = @getSelectedDocs()
- app.settings.setDocs(docs)
- @saveLink.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
-
getSelectedDocs: ->
for input in @findAllByTag 'input' when input?.checked
input.name
- onClick: (event) =>
- return if event.which isnt 1
- if event.target is @saveLink
- $.stopEvent(event)
- @save()
- return
-
onMouseDown: =>
@mouseDown = Date.now()
+ return
onDOMFocus: (event) =>
target = event.target
@@ -112,13 +82,3 @@ class app.views.DocPicker extends app.View
@delay -> $('input', target.nextElementSibling).focus()
@focusEl = target
return
-
- onEnter: =>
- @save()
- return
-
- onAppCacheProgress: (event) =>
- if event.lengthComputable
- percentage = Math.round event.loaded * 100 / event.total
- @saveLink.textContent = "Downloading\u2026 (#{percentage}%)"
- return
diff --git a/assets/javascripts/views/sidebar/sidebar.coffee b/assets/javascripts/views/sidebar/sidebar.coffee
index 8d67da39..50d88dec 100644
--- a/assets/javascripts/views/sidebar/sidebar.coffee
+++ b/assets/javascripts/views/sidebar/sidebar.coffee
@@ -22,10 +22,8 @@ class app.views.Sidebar extends app.View
@results = new app.views.Results @, @search
@docList = new app.views.DocList
- @docPicker = new app.views.DocPicker unless app.isSingleDoc()
app.on 'ready', @onReady
- $.on document, 'click', @onGlobalClick if @docPicker
return
display: ->
@@ -45,23 +43,18 @@ class app.views.Sidebar extends app.View
@render()
@view.activate()
@restoreScrollPosition()
- if view is @docPicker then @search.disable() else @search.enable()
return
render: ->
@html @view
- @append @tmpl('sidebarSettings') if @view is @docList and @docPicker
return
showDocList: ->
@showView @docList
return
- showDocPicker: =>
- @showView @docPicker
- return
-
showResults: =>
+ @display()
@showView @results
return
@@ -101,7 +94,6 @@ class app.views.Sidebar extends app.View
return
onSearching: =>
- @display()
@showResults()
return
@@ -124,23 +116,6 @@ class app.views.Sidebar extends app.View
if event.target.hasAttribute? 'data-reset-list'
$.stopEvent(event)
@onAltR()
- else if event.target.hasAttribute? 'data-light'
- $.stopEvent(event)
- document.activeElement?.blur()
- app.document.toggleLight()
- else if event.target.hasAttribute? 'data-layout'
- $.stopEvent(event)
- document.activeElement?.blur()
- app.document.toggleLayout()
- return
-
- onGlobalClick: (event) =>
- return if event.which isnt 1
- if event.target.hasAttribute? 'data-pick-docs'
- $.stopEvent(event)
- @showDocPicker()
- else if @view is @docPicker
- @showDocList() unless $.hasChild @el, event.target
return
onAltR: =>
@@ -157,3 +132,4 @@ class app.views.Sidebar extends app.View
onDocEnabled: ->
@docList.onEnabled()
@reset()
+ return
diff --git a/assets/stylesheets/application-dark.css.scss b/assets/stylesheets/application-dark.css.scss
index 678827eb..1834cde4 100644
--- a/assets/stylesheets/application-dark.css.scss
+++ b/assets/stylesheets/application-dark.css.scss
@@ -20,6 +20,7 @@
'components/header',
'components/notif',
'components/sidebar',
+ 'components/settings',
'components/content',
'components/page',
'components/fail',
diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss
index db6b3368..46fb7626 100644
--- a/assets/stylesheets/application.css.scss
+++ b/assets/stylesheets/application.css.scss
@@ -20,6 +20,7 @@
'components/header',
'components/notif',
'components/sidebar',
+ 'components/settings',
'components/content',
'components/page',
'components/fail',
diff --git a/assets/stylesheets/components/_content.scss b/assets/stylesheets/components/_content.scss
index 3e0031c7..f9dde186 100644
--- a/assets/stylesheets/components/_content.scss
+++ b/assets/stylesheets/components/_content.scss
@@ -12,7 +12,7 @@
@media #{$mediumScreen} { margin-left: $sidebarMediumWidth; }
- ._sidebar-hidden & { margin-left: $sidebarHiddenWidth; }
+ ._sidebar-hidden & { margin-left: 0; }
}
._content {
@@ -283,7 +283,6 @@
}
._docs-label {
- display: block;
overflow: hidden;
margin: 1px 0;
padding: .375rem .5rem;
@@ -292,8 +291,6 @@
display: inline-block;
vertical-align: top;
margin: .25rem;
- width: 1rem;
- height: 1rem;
}
}
diff --git a/assets/stylesheets/components/_header.scss b/assets/stylesheets/components/_header.scss
index fe60e315..50c756c2 100644
--- a/assets/stylesheets/components/_header.scss
+++ b/assets/stylesheets/components/_header.scss
@@ -12,6 +12,8 @@
height: $headerHeight;
background: $headerBackground;
border-bottom: 1px solid $headerBorder;
+ border-right: 1px solid $headerBorder;
+ @extend %border-box;
@extend %user-select-none;
@media #{$mediumScreen} { width: $sidebarMediumWidth; }
@@ -55,17 +57,13 @@
// Menu
//
-._menu-btn {
- border-right: 1px solid $headerBorder;
-}
-
._menu {
position: absolute;
z-index: 1;
top: .25rem;
right: .25rem;
width: 8rem;
- height: calc(11.5rem + 1px);
+ height: calc(13.75rem + 1px);
font-size: .875rem;
background: $contentBackground;
border: 1px solid $headerBorder;
diff --git a/assets/stylesheets/components/_mobile.scss b/assets/stylesheets/components/_mobile.scss
index 5ca8463e..7039eda0 100644
--- a/assets/stylesheets/components/_mobile.scss
+++ b/assets/stylesheets/components/_mobile.scss
@@ -11,30 +11,42 @@
body { -ms-overflow-style: -ms-autohiding-scrollbar; }
._app, ._content { overflow: visible; }
- ._app { padding-top: $headerHeight; }
- ._container { margin: 0; }
+
+ ._container, ._sidebar {
+ margin: 0;
+ padding-top: $headerHeight;
+ }
._content {
position: static;
height: auto;
margin: 0;
- padding: .75rem 1rem 2.5rem;
+ padding: .75rem 1rem 2rem;
&:before { content: none; }
}
._booting:before, ._content-loading:before { font-size: 3rem; }
- // Header
-
- ._header {
+ ._header, ._footer {
position: fixed;
- max-width: 100vw;
+ width: 100%;
}
+ ._header, ._list, ._footer {
+ width: 100%;
+ border-right: 0;
+ box-shadow: none;
+ }
+
+ ._settings { position: static; }
+ ._settings ._sidebar { padding-bottom: $headerHeight; }
+ ._settings-tabs { display: block; }
+
+ // Header
+
._header-btn { width: 2.5rem; }
._header-btn[hidden] { display: block; }
- ._menu-btn { border-right: 0; }
._search {
padding-right: .125rem;
@@ -53,8 +65,6 @@
overflow: visible;
}
- ._header, ._list, ._sidebar-footer { width: 100%; }
-
._list-item {
white-space: normal;
word-wrap: break-word;
@@ -72,15 +82,6 @@
}
}
- ._list-link { display: none; }
-
- ._sidebar-footer { box-shadow: none; }
-
- ._sidebar-footer-save {
- margin: 0;
- box-shadow: 0 1px $noteGreenBorder, 0 -1px $noteGreenBorder;
- }
-
// Notice
._notice {
diff --git a/assets/stylesheets/components/_notice.scss b/assets/stylesheets/components/_notice.scss
index 993ec3d6..0dba80ae 100644
--- a/assets/stylesheets/components/_notice.scss
+++ b/assets/stylesheets/components/_notice.scss
@@ -11,7 +11,8 @@
@media #{$mediumScreen} { left: $sidebarMediumWidth; }
- ._sidebar-hidden & { left: $sidebarHiddenWidth; }
+ ._sidebar-hidden & { left: 0; }
+
~ ._container { padding-bottom: 2.5rem; }
}
diff --git a/assets/stylesheets/components/_path.scss b/assets/stylesheets/components/_path.scss
index 5de429c3..b1c3b471 100644
--- a/assets/stylesheets/components/_path.scss
+++ b/assets/stylesheets/components/_path.scss
@@ -13,7 +13,7 @@
@media #{$mediumScreen} { left: $sidebarMediumWidth; }
- ._sidebar-hidden & { left: $sidebarHiddenWidth; }
+ ._sidebar-hidden & { left: 0; }
~ ._container { padding-bottom: 2rem; }
a:focus { outline: 0; }
diff --git a/assets/stylesheets/components/_settings.scss b/assets/stylesheets/components/_settings.scss
new file mode 100644
index 00000000..089e0732
--- /dev/null
+++ b/assets/stylesheets/components/_settings.scss
@@ -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;
+ }
+}
diff --git a/assets/stylesheets/components/_sidebar.scss b/assets/stylesheets/components/_sidebar.scss
index c330e61c..1e6b6d52 100644
--- a/assets/stylesheets/components/_sidebar.scss
+++ b/assets/stylesheets/components/_sidebar.scss
@@ -8,13 +8,13 @@
top: $headerHeight;
bottom: 0;
left: 0;
- margin-top: 1px;
overflow-x: hidden;
overflow-y: scroll;
background: $sidebarBackground;
background-clip: content-box;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: none; // IE 10 doesn't support pointer-events
+ @extend %border-box;
@extend %user-select-none;
&::-webkit-scrollbar { -webkit-appearance: none; width: 10px; }
@@ -48,26 +48,7 @@
width: 3px;
cursor: col-resize;
- ._sidebar-hidden & {
- left: 0;
- margin-left: 0;
- background: $headerBackground;
- border-right: 1px solid $headerBorder;
- width: 8px;
- cursor: pointer;
-
- &:before {
- content: '';
- position: absolute;
- top: 50%;
- left: 3px;
- margin-top: -.5rem;
- width: 1px;
- height: 1rem;
- border-left: 1px solid $textColorLighter;
- border-right: 1px solid $textColorLighter;
- }
- }
+ ._sidebar-hidden & { display: none; }
}
//
@@ -84,10 +65,7 @@
@media #{$mediumScreen} { width: $sidebarMediumWidth; }
- ._sidebar > & {
- min-height: 100%;
- padding-bottom: 3.5rem;
- }
+ ._sidebar > & { min-height: 100%; }
a:focus { outline: 0; }
}
@@ -342,7 +320,7 @@
._list-picker {
> ._list, > ._list-item {
opacity: 0;
- transition: .2s;
+ transition: opacity .2s;
}
&._in { > ._list, > ._list-item { opacity: 1; } }
@@ -354,14 +332,11 @@
position: absolute;
top: .5rem;
right: .75rem;
- width: 1rem;
- height: 1rem;
- transition: .2s;
}
._list-link {
display: block;
- margin-top: .75rem;
+ padding: .75rem 0;
font-size: .8125rem;
text-align: center;
@extend %external-link;
@@ -369,135 +344,3 @@
&:after { visibility: hidden; }
&:hover:after { visibility: visible; }
}
-
-//
-// Footer
-//
-
-._sidebar-footer {
- position: fixed;
- bottom: 0;
- left: 0;
- width: $sidebarWidth;
- background: $sidebarBackground;
- box-shadow: inset -1px 0 $sidebarBorder;
- -webkit-transform: translateZ(0);
- transform: translateZ(0);
-
- @media #{$mediumScreen} { width: $sidebarMediumWidth; }
-
- ._max-width & {
- left: calc(50% - #{$maxWidth} / 2);
- @media (max-width: #{$maxWidth}) { left: 0; }
- }
-
- &:before {
- content: '';
- position: absolute;
- bottom: 100%;
- left: 0;
- right: 1px;
- height: 1em;
- background-image: -webkit-linear-gradient(top, rgba($sidebarBackground, 0), rgba($sidebarBackground, .95));
- background-image: linear-gradient(to bottom, rgba($sidebarBackground, 0), rgba($sidebarBackground, .95));
- pointer-events: none;
- }
-}
-
-._sidebar-footer-link {
- position: relative;
- display: block;
- overflow: hidden;
- height: 2.5rem;
- line-height: 1rem;
- padding: .75rem .25rem .75rem .75rem;
- font-size: .875em;
- cursor: pointer;
- @extend %border-box;
-
- &, &:hover {
- color: inherit;
- text-decoration: none;
- }
-
- &:before {
- float: left;
- margin-right: .625rem;
- @extend %icon;
- }
-}
-
-._sidebar-footer-edit {
- display: inline-block;
-
- @if $style == 'dark' {
- &:before { @extend %icon-settings-white; }
- } @else {
- &:before { @extend %icon-settings; }
- }
-}
-
-._sidebar-footer-light {
- float: right;
- width: 2rem;
- padding: 0;
- opacity: .65;
- @extend %hide-text;
-
- &:before {
- float: none;
- position: absolute;
- top: .75rem;
- left: .25rem;
-
- @if $style == 'dark' {
- @extend %icon-light-white;
- } @else {
- @extend %icon-light;
- }
- }
-}
-
-._sidebar-footer-layout {
- float: right;
- width: 2rem;
- padding: 0;
- opacity: .65;
- @extend %hide-text;
-
- &:before {
- float: none;
- position: absolute;
- top: .75rem;
- left: .375rem;
- @if $style == 'dark' {
- @extend %icon-expand-white;
- } @else {
- @extend %icon-expand;
- }
-
- ._max-width & {
- @if $style == 'dark' {
- @extend %icon-contract-white;
- } @else {
- @extend %icon-contract;
- }
- }
- }
-
- @media (max-width: #{$maxWidth + .1rem}) { display: none; }
-}
-
-._sidebar-footer-save {
- margin-right: 1px;
- font-weight: $boldFontWeight;
- background: $noteGreenBackground;
- box-shadow: inset 0 1px $noteGreenBorder,
- 1px 0 $noteGreenBorder;
-
- @if $style == 'dark' {
- &:before { @extend %icon-check-white; }
- } @else {
- &:before { @extend %icon-check; }
- }
-}
diff --git a/assets/stylesheets/global/_base.scss b/assets/stylesheets/global/_base.scss
index 53adbe4e..58012df4 100644
--- a/assets/stylesheets/global/_base.scss
+++ b/assets/stylesheets/global/_base.scss
@@ -166,6 +166,11 @@ section, main {
outline: 0;
}
+label {
+ display: block;
+ @extend %user-select-none;
+}
+
input, button {
margin: 0;
font-family: inherit;
@@ -175,6 +180,12 @@ input, button {
@extend %border-box;
}
+input[type=checkbox] {
+ width: 1rem;
+ height: 1rem;
+ cursor: pointer;
+}
+
button {
padding: 0;
background: none;
diff --git a/assets/stylesheets/global/_icons.scss b/assets/stylesheets/global/_icons.scss
index 9bf033a3..4252d574 100644
--- a/assets/stylesheets/global/_icons.scss
+++ b/assets/stylesheets/global/_icons.scss
@@ -4,7 +4,7 @@
width: 1rem;
height: 1rem;
background-image: image-url('icons.png');
- background-size: 4rem 6rem;
+ background-size: 4rem 3rem;
}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) {
@@ -35,23 +35,13 @@
%icon-search { background-position: -1rem 0; }
%icon-link { background-position: -2.25rem -.25rem; }
%icon-clear { background-position: -3rem 0; }
-%icon-settings { background-position: 0 -1rem; }
-%icon-check { background-position: -1rem -1rem; }
-%icon-path { background-position: 0 -2rem; }
-%icon-search-white { background-position: -1rem -2rem; }
-%icon-dir-white { background-position: -2rem -2rem; }
-%icon-link-white { background-position: -3.25rem -2.25rem; }
-%icon-settings-white { background-position: 0 -3rem; }
-%icon-check-white { background-position: -1rem -3rem; }
-%icon-light { background-position: -2rem -3rem; }
-%icon-light-white { background-position: -3rem -3rem; }
-%icon-expand { background-position: 0 -4rem; }
-%icon-contract { background-position: -1rem -4rem; }
-%icon-expand-white { background-position: -2rem -4rem; }
-%icon-contract-white { background-position: -3rem -4rem; }
-%icon-clipboard { background-position: 0 -5rem; }
-%icon-clipboard-white { background-position: -1rem -5rem; }
-%icon-close-white { background-position: -2rem -5rem; }
+%icon-path { background-position: 0 -1rem; }
+%icon-search-white { background-position: -1rem -1rem; }
+%icon-dir-white { background-position: -2rem -1rem; }
+%icon-link-white { background-position: -3.25rem -1.25rem; }
+%icon-clipboard { background-position: 0 -2rem; }
+%icon-clipboard-white { background-position: -1rem -2rem; }
+%icon-close-white { background-position: -2rem -2rem; }
._icon-codeceptjs:before { background-position: -3rem 0; }
._icon-codeception:before { background-position: -4rem 0; }
diff --git a/assets/stylesheets/global/_variables-dark.scss b/assets/stylesheets/global/_variables-dark.scss
index 9b4ee78f..aeb36181 100644
--- a/assets/stylesheets/global/_variables-dark.scss
+++ b/assets/stylesheets/global/_variables-dark.scss
@@ -9,7 +9,6 @@ $maxWidth: 80rem;
$headerHeight: 3rem;
$sidebarWidth: 20rem;
$sidebarMediumWidth: 16rem;
-$sidebarHiddenWidth: 9px;
$contentBackground: #33373a;
$documentBackground: $contentBackground;
@@ -17,6 +16,7 @@ $documentBackground: $contentBackground;
$textColor: #cbd0d0;
$textColorLight: #9da5ad;
$textColorLighter: #77787a;
+$textColorRed: #f44336;
$inputFocusBorder: false;
diff --git a/assets/stylesheets/global/_variables.scss b/assets/stylesheets/global/_variables.scss
index 68d4358b..bde5f6cd 100644
--- a/assets/stylesheets/global/_variables.scss
+++ b/assets/stylesheets/global/_variables.scss
@@ -9,7 +9,6 @@ $maxWidth: 80rem;
$headerHeight: 3rem;
$sidebarWidth: 20rem;
$sidebarMediumWidth: 16rem;
-$sidebarHiddenWidth: 9px;
$contentBackground: #fff;
$documentBackground: #fafafa;
@@ -17,6 +16,7 @@ $documentBackground: #fafafa;
$textColor: #333;
$textColorLight: #666;
$textColorLighter: #888;
+$textColorRed: #f44336;
$inputFocusBorder: #35b5f4;
diff --git a/lib/app.rb b/lib/app.rb
index bb19a046..6fd711c6 100644
--- a/lib/app.rb
+++ b/lib/app.rb
@@ -235,7 +235,7 @@ class App < Sinatra::Application
erb :index
end
- %w(offline about news help).each do |page|
+ %w(settings offline about news help).each do |page|
get "/#{page}" do
if supports_js_redirection?
redirect_via_js "/#{page}"
diff --git a/public/icons/ui/check-white/SOURCE b/public/icons/ui/check-white/SOURCE
deleted file mode 100644
index 766f1fbe..00000000
--- a/public/icons/ui/check-white/SOURCE
+++ /dev/null
@@ -1 +0,0 @@
-http://happytodesign.com/hicons/
diff --git a/public/icons/ui/check-white/check-white.png b/public/icons/ui/check-white/check-white.png
deleted file mode 100644
index a9f4e476..00000000
Binary files a/public/icons/ui/check-white/check-white.png and /dev/null differ
diff --git a/public/icons/ui/check-white/check-white@2x.png b/public/icons/ui/check-white/check-white@2x.png
deleted file mode 100644
index e6fcff05..00000000
Binary files a/public/icons/ui/check-white/check-white@2x.png and /dev/null differ
diff --git a/public/icons/ui/check/SOURCE b/public/icons/ui/check/SOURCE
deleted file mode 100644
index 766f1fbe..00000000
--- a/public/icons/ui/check/SOURCE
+++ /dev/null
@@ -1 +0,0 @@
-http://happytodesign.com/hicons/
diff --git a/public/icons/ui/check/check.png b/public/icons/ui/check/check.png
deleted file mode 100644
index 702b0578..00000000
Binary files a/public/icons/ui/check/check.png and /dev/null differ
diff --git a/public/icons/ui/check/check@2x.png b/public/icons/ui/check/check@2x.png
deleted file mode 100644
index a5e407a9..00000000
Binary files a/public/icons/ui/check/check@2x.png and /dev/null differ
diff --git a/public/icons/ui/contract/16.png b/public/icons/ui/contract/16.png
deleted file mode 100644
index d23cfd88..00000000
Binary files a/public/icons/ui/contract/16.png and /dev/null differ
diff --git a/public/icons/ui/contract/16@2x.png b/public/icons/ui/contract/16@2x.png
deleted file mode 100644
index a9373149..00000000
Binary files a/public/icons/ui/contract/16@2x.png and /dev/null differ
diff --git a/public/icons/ui/expand/16.png b/public/icons/ui/expand/16.png
deleted file mode 100644
index aeef7f9d..00000000
Binary files a/public/icons/ui/expand/16.png and /dev/null differ
diff --git a/public/icons/ui/expand/16@2x.png b/public/icons/ui/expand/16@2x.png
deleted file mode 100644
index 63381f8a..00000000
Binary files a/public/icons/ui/expand/16@2x.png and /dev/null differ
diff --git a/public/icons/ui/light-white/SOURCE b/public/icons/ui/light-white/SOURCE
deleted file mode 100644
index ffa79609..00000000
--- a/public/icons/ui/light-white/SOURCE
+++ /dev/null
@@ -1 +0,0 @@
-http://www.entypo.com/
diff --git a/public/icons/ui/light-white/light.png b/public/icons/ui/light-white/light.png
deleted file mode 100644
index cacc3f9d..00000000
Binary files a/public/icons/ui/light-white/light.png and /dev/null differ
diff --git a/public/icons/ui/light-white/light@2x.png b/public/icons/ui/light-white/light@2x.png
deleted file mode 100644
index 39e76205..00000000
Binary files a/public/icons/ui/light-white/light@2x.png and /dev/null differ
diff --git a/public/icons/ui/light/SOURCE b/public/icons/ui/light/SOURCE
deleted file mode 100644
index ffa79609..00000000
--- a/public/icons/ui/light/SOURCE
+++ /dev/null
@@ -1 +0,0 @@
-http://www.entypo.com/
diff --git a/public/icons/ui/light/light.png b/public/icons/ui/light/light.png
deleted file mode 100644
index 4e76ed5f..00000000
Binary files a/public/icons/ui/light/light.png and /dev/null differ
diff --git a/public/icons/ui/light/light@2x.png b/public/icons/ui/light/light@2x.png
deleted file mode 100644
index 73594f24..00000000
Binary files a/public/icons/ui/light/light@2x.png and /dev/null differ
diff --git a/public/icons/ui/settings-white/SOURCE b/public/icons/ui/settings-white/SOURCE
deleted file mode 100644
index fa3cf541..00000000
--- a/public/icons/ui/settings-white/SOURCE
+++ /dev/null
@@ -1 +0,0 @@
-http://gemicon.net/
diff --git a/public/icons/ui/settings-white/settings-white.png b/public/icons/ui/settings-white/settings-white.png
deleted file mode 100755
index 49c53a40..00000000
Binary files a/public/icons/ui/settings-white/settings-white.png and /dev/null differ
diff --git a/public/icons/ui/settings-white/settings-white@2x.png b/public/icons/ui/settings-white/settings-white@2x.png
deleted file mode 100755
index adfda16b..00000000
Binary files a/public/icons/ui/settings-white/settings-white@2x.png and /dev/null differ
diff --git a/public/icons/ui/settings/SOURCE b/public/icons/ui/settings/SOURCE
deleted file mode 100644
index fa3cf541..00000000
--- a/public/icons/ui/settings/SOURCE
+++ /dev/null
@@ -1 +0,0 @@
-http://gemicon.net/
diff --git a/public/icons/ui/settings/settings.png b/public/icons/ui/settings/settings.png
deleted file mode 100755
index 3e4925a9..00000000
Binary files a/public/icons/ui/settings/settings.png and /dev/null differ
diff --git a/public/icons/ui/settings/settings@2x.png b/public/icons/ui/settings/settings@2x.png
deleted file mode 100755
index 707390e2..00000000
Binary files a/public/icons/ui/settings/settings@2x.png and /dev/null differ
diff --git a/public/robots.txt b/public/robots.txt
index 14267e90..09a96335 100644
--- a/public/robots.txt
+++ b/public/robots.txt
@@ -1,2 +1,2 @@
User-agent: *
-Allow: /
\ No newline at end of file
+Disallow: /settings
\ No newline at end of file
diff --git a/views/app.erb b/views/app.erb
index 0b3104e0..92d83a61 100644
--- a/views/app.erb
+++ b/views/app.erb
@@ -1,7 +1,7 @@
" role="application">