Add "Pin watched threads" option. #187
Also add Alt+click and menu item to watch threads in catalog.
This commit is contained in:
parent
bccafdfbc1
commit
8db43ab04b
@ -589,6 +589,7 @@ http://iqdb.org/?url=%TURL
|
|||||||
'Index Sort': 'bump'
|
'Index Sort': 'bump'
|
||||||
'Index Size': 'small'
|
'Index Size': 'small'
|
||||||
'Show Replies': true
|
'Show Replies': true
|
||||||
|
'Pin Watched Threads': true
|
||||||
'Anchor Hidden Threads': true
|
'Anchor Hidden Threads': true
|
||||||
'Refreshed Navigation': false
|
'Refreshed Navigation': false
|
||||||
|
|
||||||
|
|||||||
@ -24,25 +24,27 @@ Index =
|
|||||||
Header.addShortcut @button, 1
|
Header.addShortcut @button, 1
|
||||||
|
|
||||||
repliesEntry = el: UI.checkbox 'Show Replies', ' Show replies'
|
repliesEntry = el: UI.checkbox 'Show Replies', ' Show replies'
|
||||||
|
pinEntry = el: UI.checkbox 'Pin Watched Threads', ' Pin watched threads'
|
||||||
anchorEntry = el: UI.checkbox 'Anchor Hidden Threads', ' Anchor hidden threads'
|
anchorEntry = el: UI.checkbox 'Anchor Hidden Threads', ' Anchor hidden threads'
|
||||||
refNavEntry = el: UI.checkbox 'Refreshed Navigation', ' Refreshed navigation'
|
refNavEntry = el: UI.checkbox 'Refreshed Navigation', ' Refreshed navigation'
|
||||||
anchorEntry.el.title = 'Move hidden threads at the end of the index.'
|
pinEntry.el.title = 'Move watched threads to the start of the index.'
|
||||||
|
anchorEntry.el.title = 'Move hidden threads to the end of the index.'
|
||||||
refNavEntry.el.title = 'Refresh index when navigating through pages.'
|
refNavEntry.el.title = 'Refresh index when navigating through pages.'
|
||||||
for label in [repliesEntry, anchorEntry, refNavEntry]
|
for label in [repliesEntry, pinEntry, anchorEntry, refNavEntry]
|
||||||
input = label.el.firstChild
|
input = label.el.firstChild
|
||||||
{name} = input
|
{name} = input
|
||||||
$.on input, 'change', $.cb.checked
|
$.on input, 'change', $.cb.checked
|
||||||
switch name
|
switch name
|
||||||
when 'Show Replies'
|
when 'Show Replies'
|
||||||
$.on input, 'change', @cb.replies
|
$.on input, 'change', @cb.replies
|
||||||
when 'Anchor Hidden Threads'
|
when 'Pin Watched Threads', 'Anchor Hidden Threads'
|
||||||
$.on input, 'change', @cb.sort
|
$.on input, 'change', @cb.sort
|
||||||
|
|
||||||
Header.menu.addEntry
|
Header.menu.addEntry
|
||||||
el: $.el 'span',
|
el: $.el 'span',
|
||||||
textContent: 'Index Navigation'
|
textContent: 'Index Navigation'
|
||||||
order: 98
|
order: 98
|
||||||
subEntries: [repliesEntry, anchorEntry, refNavEntry]
|
subEntries: [repliesEntry, pinEntry, anchorEntry, refNavEntry]
|
||||||
|
|
||||||
$.addClass doc, 'index-loading', "#{Conf['Index Mode'].replace /\ /g, '-'}-mode"
|
$.addClass doc, 'index-loading', "#{Conf['Index Mode'].replace /\ /g, '-'}-mode"
|
||||||
@root = $.el 'div', className: 'board'
|
@root = $.el 'div', className: 'board'
|
||||||
@ -252,9 +254,9 @@ Index =
|
|||||||
1
|
1
|
||||||
else
|
else
|
||||||
+window.location.pathname.split('/')[2] or 1
|
+window.location.pathname.split('/')[2] or 1
|
||||||
userPageNav: (page) ->
|
userPageNav: (page, noRefresh) ->
|
||||||
state = Index.pushState {page}
|
state = Index.pushState {page}
|
||||||
if Conf['Refreshed Navigation']
|
if Conf['Refreshed Navigation'] and !noRefresh
|
||||||
Index.update state
|
Index.update state
|
||||||
else
|
else
|
||||||
Index.pageLoad state if state.page
|
Index.pageLoad state if state.page
|
||||||
@ -542,7 +544,7 @@ Index =
|
|||||||
# Sticky threads
|
# Sticky threads
|
||||||
Index.sortOnTop (thread) -> thread.isSticky
|
Index.sortOnTop (thread) -> thread.isSticky
|
||||||
# Highlighted threads
|
# Highlighted threads
|
||||||
Index.sortOnTop (thread) -> thread.isOnTop
|
Index.sortOnTop (thread) -> thread.isOnTop or Conf['Pin Watched Threads'] and ThreadWatcher.isWatched thread
|
||||||
# Non-hidden threads
|
# Non-hidden threads
|
||||||
Index.sortOnTop((thread) -> !thread.isHidden) if Conf['Anchor Hidden Threads']
|
Index.sortOnTop((thread) -> !thread.isHidden) if Conf['Anchor Hidden Threads']
|
||||||
|
|
||||||
@ -561,6 +563,11 @@ Index =
|
|||||||
nodes = Index.buildCatalogViews()
|
nodes = Index.buildCatalogViews()
|
||||||
Index.sizeCatalogViews nodes
|
Index.sizeCatalogViews nodes
|
||||||
else
|
else
|
||||||
|
if Index.followedThreadID?
|
||||||
|
i = 0
|
||||||
|
i++ while Index.followedThreadID isnt Get.threadFromRoot(Index.sortedNodes[i]).ID
|
||||||
|
page = i // Index.threadsNumPerPage + 1
|
||||||
|
Index.pushState {page} if page isnt Index.getCurrentPage()
|
||||||
nodes = Index.buildSinglePage Index.getCurrentPage()
|
nodes = Index.buildSinglePage Index.getCurrentPage()
|
||||||
$.rmAll Index.root
|
$.rmAll Index.root
|
||||||
$.rmAll Header.hover
|
$.rmAll Header.hover
|
||||||
@ -569,6 +576,8 @@ Index =
|
|||||||
else
|
else
|
||||||
Index.buildReplies nodes if Conf['Show Replies']
|
Index.buildReplies nodes if Conf['Show Replies']
|
||||||
Index.buildStructure nodes
|
Index.buildStructure nodes
|
||||||
|
if Index.followedThreadID? and (post = g.posts["#{g.BOARD}.#{Index.followedThreadID}"])
|
||||||
|
Header.scrollTo post.nodes.root
|
||||||
|
|
||||||
buildSinglePage: (pageNum) ->
|
buildSinglePage: (pageNum) ->
|
||||||
nodesPerPage = Index.threadsNumPerPage
|
nodesPerPage = Index.threadsNumPerPage
|
||||||
|
|||||||
@ -890,6 +890,7 @@ span.hide-announcement {
|
|||||||
-webkit-align-self: stretch;
|
-webkit-align-self: stretch;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
}
|
}
|
||||||
|
.catalog-thread.watched .werkTyme-filename,
|
||||||
.filter-highlight .werkTyme-filename {
|
.filter-highlight .werkTyme-filename {
|
||||||
border: 2px solid rgba(255, 0, 0, .5);
|
border: 2px solid rgba(255, 0, 0, .5);
|
||||||
}
|
}
|
||||||
@ -911,6 +912,7 @@ span.hide-announcement {
|
|||||||
.filter-highlight > .reply {
|
.filter-highlight > .reply {
|
||||||
box-shadow: -5px 0 rgba(255, 0, 0, .5);
|
box-shadow: -5px 0 rgba(255, 0, 0, .5);
|
||||||
}
|
}
|
||||||
|
.catalog-thread.watched .catalog-thumb,
|
||||||
.filter-highlight .catalog-thumb {
|
.filter-highlight .catalog-thumb {
|
||||||
border: 2px solid rgba(255, 0, 0, .5);
|
border: 2px solid rgba(255, 0, 0, .5);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,29 @@ ThreadWatcher =
|
|||||||
Thread.callbacks.push
|
Thread.callbacks.push
|
||||||
name: 'Thread Watcher'
|
name: 'Thread Watcher'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
CatalogThread.callbacks.push
|
||||||
|
name: 'Thread Watcher'
|
||||||
|
cb: @catalogNode
|
||||||
|
|
||||||
|
if g.VIEW is 'index' and Conf['JSON Navigation'] and Conf['Menu'] and g.BOARD.ID isnt 'f'
|
||||||
|
Menu.menu.addEntry
|
||||||
|
el: $.el 'a', href: 'javascript:;'
|
||||||
|
order: 6
|
||||||
|
open: ({thread}) ->
|
||||||
|
return false if Conf['Index Mode'] isnt 'catalog'
|
||||||
|
@el.textContent = if ThreadWatcher.isWatched thread
|
||||||
|
'Unwatch thread'
|
||||||
|
else
|
||||||
|
'Watch thread'
|
||||||
|
$.off @el, 'click', @cb if @cb
|
||||||
|
@cb = ->
|
||||||
|
$.event 'CloseMenu'
|
||||||
|
ThreadWatcher.toggle thread
|
||||||
|
$.on @el, 'click', @cb
|
||||||
|
true
|
||||||
|
|
||||||
|
isWatched: (thread) ->
|
||||||
|
ThreadWatcher.db?.get {boardID: thread.board.ID, threadID: thread.ID}
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
toggler = $.el 'img',
|
toggler = $.el 'img',
|
||||||
@ -49,6 +72,13 @@ ThreadWatcher =
|
|||||||
$.on toggler, 'click', ThreadWatcher.cb.toggle
|
$.on toggler, 'click', ThreadWatcher.cb.toggle
|
||||||
$.before $('input', @OP.nodes.post), toggler
|
$.before $('input', @OP.nodes.post), toggler
|
||||||
|
|
||||||
|
catalogNode: ->
|
||||||
|
$.addClass @nodes.root, 'watched' if ThreadWatcher.isWatched @thread
|
||||||
|
$.on @nodes.thumb.parentNode, 'click', (e) =>
|
||||||
|
return unless e.button is 0 and e.altKey
|
||||||
|
ThreadWatcher.toggle @thread
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
ready: ->
|
ready: ->
|
||||||
$.off d, '4chanXInitFinished', ThreadWatcher.ready
|
$.off d, '4chanXInitFinished', ThreadWatcher.ready
|
||||||
return unless Main.isThisPageLegit()
|
return unless Main.isThisPageLegit()
|
||||||
@ -83,7 +113,10 @@ ThreadWatcher =
|
|||||||
ThreadWatcher.refresh()
|
ThreadWatcher.refresh()
|
||||||
$.event 'CloseMenu'
|
$.event 'CloseMenu'
|
||||||
toggle: ->
|
toggle: ->
|
||||||
ThreadWatcher.toggle Get.postFromNode(@).thread
|
{thread} = Get.postFromNode @
|
||||||
|
Index.followedThreadID = thread.ID
|
||||||
|
ThreadWatcher.toggle thread
|
||||||
|
delete Index.followedThreadID
|
||||||
rm: ->
|
rm: ->
|
||||||
[boardID, threadID] = @parentNode.dataset.fullID.split '.'
|
[boardID, threadID] = @parentNode.dataset.fullID.split '.'
|
||||||
ThreadWatcher.rm boardID, +threadID
|
ThreadWatcher.rm boardID, +threadID
|
||||||
@ -240,14 +273,17 @@ ThreadWatcher =
|
|||||||
for threadID in threads.keys
|
for threadID in threads.keys
|
||||||
thread = threads[threadID]
|
thread = threads[threadID]
|
||||||
toggler = $ '.watch-thread-link', thread.OP.nodes.post
|
toggler = $ '.watch-thread-link', thread.OP.nodes.post
|
||||||
watched = ThreadWatcher.db.get {boardID: thread.board.ID, threadID}
|
helper = if ThreadWatcher.isWatched thread then ['addClass', 'Unwatch'] else ['rmClass', 'Watch']
|
||||||
helper = if watched then ['addClass', 'Unwatch'] else ['rmClass', 'Watch']
|
|
||||||
$[helper[0]] toggler, 'watched'
|
$[helper[0]] toggler, 'watched'
|
||||||
|
$[helper[0]] thread.catalogView.nodes.root, 'watched' if thread.catalogView
|
||||||
toggler.title = "#{helper[1]} Thread"
|
toggler.title = "#{helper[1]} Thread"
|
||||||
|
|
||||||
for refresher in ThreadWatcher.menu.refreshers
|
for refresher in ThreadWatcher.menu.refreshers
|
||||||
refresher()
|
refresher()
|
||||||
return
|
|
||||||
|
if Index.nodes and Conf['Pin Watched Threads']
|
||||||
|
Index.sort()
|
||||||
|
Index.buildIndex()
|
||||||
|
|
||||||
toggle: (thread) ->
|
toggle: (thread) ->
|
||||||
boardID = thread.board.ID
|
boardID = thread.board.ID
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user