-
-
Save wfdewith/978e4f8e09f481a480cb1bf645e8d518 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local DocSettings = require("docsettings") | |
local ffiUtil = require("ffi/util") | |
local FileChooser = require("ui/widget/filechooser") | |
local _ = require("gettext") | |
--[[ | |
This algorithm sorts books as follows. | |
First, it sorts them into three blocks in the following order: in progress, | |
unread and finished. | |
The in progress block is then further sorted by access time, where the last | |
accessed book is sorted first. If the access time is equal, they will be sorted | |
by their name. Equal access times are not rare on FAT32 because it is only | |
precise to a day. | |
The other blocks are sorted only by name. | |
Directories are considered to have the properties of their 'smallest' child | |
item, except for the name. | |
--]] | |
local function weirdsort(x, y) | |
local a = x.sort_item | |
local b = y.sort_item | |
-- If any sort_item is nil, they are empty directories | |
if not a then | |
return false | |
elseif not b then | |
return true | |
end | |
-- Note that we use the original x and y for the strcoll calls, to sort by | |
-- the original directory name. | |
if a.opened == b.opened then | |
if a.opened then | |
if a.status == b.status then | |
if a.status == "reading" then | |
if a.attr.access == b.attr.access then | |
return ffiUtil.strcoll(x.text, y.text) | |
else | |
return a.attr.access > b.attr.access | |
end | |
else | |
return ffiUtil.strcoll(x.text, y.text) | |
end | |
else | |
return a.status == "reading" | |
end | |
else | |
return ffiUtil.strcoll(x.text, y.text) | |
end | |
else | |
if a.opened then | |
return a.status == "reading" | |
else | |
return b.status ~= "reading" | |
end | |
end | |
end | |
FileChooser.collates.weirdsort = { | |
text = _("Wim's custom sort"), | |
menu_order = 999, | |
can_collate_mixed = true, | |
init_sort_func = function(cache) | |
return weirdsort, cache | |
end, | |
mandatory_func = function(item) | |
return item.opened and string.format("%d %%", 100 * item.percent_finished) or "–" | |
end, | |
item_func = function(item) | |
if item.attr.mode == "file" then | |
local percent_finished, summary | |
item.opened = DocSettings:hasSidecarFile(item.path) | |
if item.opened then | |
local doc_settings = DocSettings:open(item.path) | |
percent_finished = doc_settings:readSetting("percent_finished") | |
summary = doc_settings:readSetting("summary") | |
end | |
item.percent_finished = percent_finished or 0 | |
item.status = summary and summary.status or nil | |
item.sort_item = item | |
elseif item.attr.mode == "directory" then | |
local function smallest_child(dirs, files) | |
local first | |
if #dirs > 0 then | |
first = dirs[1] | |
elseif #files > 0 then | |
first = files[1] | |
end | |
for i, d in ipairs(dirs) do | |
if weirdsort(d.sort_item, first) then | |
first = d.sort_item | |
end | |
end | |
for i, f in ipairs(files) do | |
if weirdsort(f.sort_item, first) then | |
first = f.sort_item | |
end | |
end | |
return first | |
end | |
local dirs, files = FileChooser:getList(item.path, FileChooser.collates.weirdsort) | |
for i, d in ipairs(dirs) do | |
local subdirs, subfiles = FileChooser:getList(d.path, FileChooser.collates.weirdsort) | |
d.sort_item = smallest_child(subdirs, subfiles) | |
end | |
item.sort_item = smallest_child(dirs, files) | |
end | |
return item | |
end, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment