123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- class FileList extends Class
- constructor: (@site, @inner_path, @is_owner=false) ->
- @need_update = true
- @error = null
- @url_root = "/list/" + @site + "/"
- if @inner_path
- @inner_path += "/"
- @url_root += @inner_path
- @log("inited", @url_root)
- @item_list = new FileItemList(@inner_path)
- @item_list.items = @item_list.items
- @menu_create = new Menu()
- @select_action = null
- @selected = {}
- @selected_items_num = 0
- @selected_items_size = 0
- @selected_optional_empty_num = 0
- isSelectedAll: ->
- false
- update: =>
- @item_list.update =>
- document.body.classList.add("loaded")
- getHref: (inner_path) =>
- return "/" + @site + "/" + inner_path
- getListHref: (inner_path) =>
- return "/list/" + @site + "/" + inner_path
- getEditHref: (inner_path, mode=null) =>
- href = @url_root + "?file=" + inner_path
- if mode
- href += "&edit_mode=#{mode}"
- return href
- checkSelectedItems: =>
- @selected_items_num = 0
- @selected_items_size = 0
- @selected_optional_empty_num = 0
- for item in @item_list.items
- if @selected[item.inner_path]
- @selected_items_num += 1
- @selected_items_size += item.size
- optional_info = @item_list.getOptionalInfo(item.inner_path)
- if optional_info and not optional_info.downloaded_percent > 0
- @selected_optional_empty_num += 1
- handleMenuCreateClick: =>
- @menu_create.items = []
- @menu_create.items.push ["File", @handleNewFileClick]
- @menu_create.items.push ["Directory", @handleNewDirectoryClick]
- @menu_create.toggle()
- return false
- handleNewFileClick: =>
- Page.cmd "wrapperPrompt", "New file name:", (file_name) =>
- window.top.location.href = @getEditHref(@inner_path + file_name, "new")
- return false
- handleNewDirectoryClick: =>
- Page.cmd "wrapperPrompt", "New directory name:", (res) =>
- alert("directory name #{res}")
- return false
- handleSelectClick: (e) =>
- return false
- handleSelectEnd: (e) =>
- document.body.removeEventListener('mouseup', @handleSelectEnd)
- @select_action = null
- handleSelectMousedown: (e) =>
- inner_path = e.currentTarget.attributes.inner_path.value
- if @selected[inner_path]
- delete @selected[inner_path]
- @select_action = "deselect"
- else
- @selected[inner_path] = true
- @select_action = "select"
- @checkSelectedItems()
- document.body.addEventListener('mouseup', @handleSelectEnd)
- e.stopPropagation()
- Page.projector.scheduleRender()
- return false
- handleRowMouseenter: (e) =>
- if e.buttons and @select_action
- inner_path = e.target.attributes.inner_path.value
- if @select_action == "select"
- @selected[inner_path] = true
- else
- delete @selected[inner_path]
- @checkSelectedItems()
- Page.projector.scheduleRender()
- return false
- handleSelectbarCancel: =>
- @selected = {}
- @checkSelectedItems()
- Page.projector.scheduleRender()
- return false
- handleSelectbarDelete: (e, remove_optional=false) =>
- for inner_path of @selected
- optional_info = @item_list.getOptionalInfo(inner_path)
- delete @selected[inner_path]
- if optional_info and not remove_optional
- Page.cmd "optionalFileDelete", inner_path
- else
- Page.cmd "fileDelete", inner_path
- @need_update = true
- Page.projector.scheduleRender()
- @checkSelectedItems()
- return false
- handleSelectbarRemoveOptional: (e) =>
- return @handleSelectbarDelete(e, true)
- renderSelectbar: =>
- h("div.selectbar", {classes: {visible: @selected_items_num > 0}}, [
- "Selected:",
- h("span.info", [
- h("span.num", "#{@selected_items_num} files"),
- h("span.size", "(#{Text.formatSize(@selected_items_size)})"),
- ])
- h("div.actions", [
- if @selected_optional_empty_num > 0
- h("a.action.delete.remove_optional", {href: "#", onclick: @handleSelectbarRemoveOptional}, "Delete and remove optional")
- else
- h("a.action.delete", {href: "#", onclick: @handleSelectbarDelete}, "Delete")
- ])
- h("a.cancel.link", {href: "#", onclick: @handleSelectbarCancel}, "Cancel")
- ])
- renderHead: =>
- parent_links = []
- inner_path_parent = ""
- for parent_dir in @inner_path.split("/")
- if not parent_dir
- continue
- if inner_path_parent
- inner_path_parent += "/"
- inner_path_parent += "#{parent_dir}"
- parent_links.push(
- [" / ", h("a", {href: @getListHref(inner_path_parent)}, parent_dir)]
- )
- return h("div.tr.thead", h("div.td.full",
- h("a", {href: @getListHref("")}, "root"),
- parent_links
- ))
- renderItemCheckbox: (item) =>
- if not @item_list.hasPermissionDelete(item)
- return [" "]
- return h("a.checkbox-outer", {
- href: "#Select",
- onmousedown: @handleSelectMousedown,
- onclick: @handleSelectClick,
- inner_path: item.inner_path
- }, h("span.checkbox"))
- renderItem: (item) =>
- if item.type == "parent"
- href = @url_root.replace(/^(.*)\/.{2,255}?$/, "$1/")
- else if item.type == "dir"
- href = @url_root + item.name
- else
- href = @url_root.replace(/^\/list\//, "/") + item.name
- inner_path = @inner_path + item.name
- href_edit = @getEditHref(inner_path)
- is_dir = item.type in ["dir", "parent"]
- ext = item.name.split(".").pop()
- is_editing = inner_path == Page.file_editor?.inner_path
- is_editable = not is_dir and item.size < 1024 * 1024 and ext not in window.BINARY_EXTENSIONS
- is_modified = @item_list.isModified(inner_path)
- is_added = @item_list.isAdded(inner_path)
- optional_info = @item_list.getOptionalInfo(inner_path)
- style = ""
- title = ""
- if optional_info
- downloaded_percent = optional_info.downloaded_percent
- if not downloaded_percent
- downloaded_percent = 0
- style += "background: linear-gradient(90deg, #fff6dd, #{downloaded_percent}%, white, #{downloaded_percent}%, white);"
- is_added = false
- if item.ignored
- is_added = false
- if is_modified then title += " (modified)"
- if is_added then title += " (new)"
- if optional_info or item.optional_empty then title += " (optional)"
- if item.ignored then title += " (ignored from content.json)"
- classes = {
- "type-#{item.type}": true, editing: is_editing, nobuttons: not is_editable, selected: @selected[inner_path],
- modified: is_modified, added: is_added, ignored: item.ignored, optional: optional_info, optional_empty: item.optional_empty
- }
- h("div.tr", {key: item.name, classes: classes, style: style, onmouseenter: @handleRowMouseenter, inner_path: inner_path}, [
- h("div.td.pre", {title: title},
- @renderItemCheckbox(item)
- ),
- h("div.td.name", h("a.link", {href: href}, item.name))
- h("div.td.buttons", if is_editable then h("a.edit", {href: href_edit}, if Page.site_info.settings.own then "Edit" else "View"))
- h("div.td.size", if is_dir then "[DIR]" else Text.formatSize(item.size))
- ])
- renderItems: =>
- return [
- if @item_list.error and not @item_list.items.length and not @item_list.updating then [
- h("div.tr", {key: "error"}, h("div.td.full.error", @item_list.error))
- ],
- if @inner_path then @renderItem({"name": "..", type: "parent", size: 0})
- @item_list.items.map @renderItem
- ]
- renderFoot: =>
- files = (item for item in @item_list.items when item.type not in ["parent", "dir"])
- dirs = (item for item in @item_list.items when item.type == "dir")
- if files.length
- total_size = (item.size for file in files).reduce (a, b) -> a + b
- else
- total_size = 0
- foot_text = "Total: "
- foot_text += "#{dirs.length} dir, #{files.length} file in #{Text.formatSize(total_size)}"
- return [
- if dirs.length or files.length or Page.site_info?.settings?.own
- h("div.tr.foot-info.foot", h("div.td.full", [
- if @item_list.updating
- "Updating file list..."
- else
- if dirs.length or files.length then foot_text
- if Page.site_info?.settings?.own
- h("div.create", [
- h("a.link", {href: "#Create+new+file", onclick: @handleNewFileClick}, "+ New")
- @menu_create.render()
- ])
- ]))
- ]
- render: =>
- if @need_update
- @update()
- @need_update = false
- if not @item_list.items
- return []
- return h("div.files", [
- @renderSelectbar(),
- @renderHead(),
- h("div.tbody", @renderItems()),
- @renderFoot()
- ])
- window.FileList = FileList
|