Action

Tag Spinner

Posted by @galtenberg, Last update 25 days ago

Display multiple drafts based on tag.

Options to shuffle (to retrieve older drafts), require multiple tags, add backlinks.

Code options allow omitting tags, different quantities of drafts, modal defaults.

(Requires Drafts v33 or later, for Tag object and segmented control.)

Steps

  • script

    // This script requires a reusable draft – either set a UUID of a preferred draft, or one will be created with a tag designated below
    
    const pinnedDraftUUID = ""
    const pinnedDraftTag = "tag-spinner"
    
    ////// Other Preferences //////
    
    const amtList = [1, 4, 12]             // add any amounts you like
    const amtDefault = 4
    
    const keepVersions = 10                // only keep this many versions
    
    const pickRandomTag = false
    const linkDefault = "None"
    const shuffleDefault = false
    
    // Any tags you'd like ignored
    const omitTags = [pinnedDraftTag, 'ignore-tag-1', 'ignore-tag-2']
    
    ///////////////////////////////
    
    const pinnedDraft = pinnedDraftUUID.length
      ? Draft.find(pinnedDraftUUID)
      : Draft.query("", "all", [pinnedDraftTag])[0] || new Draft
    
    if (!pinnedDraftUUID.length && pinnedDraftTag.length)
      pinnedDraft.addTag(pinnedDraftTag)
    
    ///////////////////////////////
    
    const allowedTags = [...new Set(['tagged'].concat(Tag.query('').filter(x => !omitTags.includes(x)).sort()))]
    
    const randomIndex = (array) => Math.floor(Math.random() * array.length)
    
    ///////////////////////////////
    
    const p = Prompt.create()
    p.title = "Load Drafts Tagged"
    
    p.addPicker("tagPicker", "", [allowedTags], [pickRandomTag ? randomIndex(allowedTags) : 0])
    
    p.addSegmentedControl("count", "", [...amtList.map(a => a.toString()), "All"], amtDefault.toString())
    
    p.addSegmentedControl("links", "Add Links", ["None", "UUID", "Title"], linkDefault)
    
    p.addSwitch("shuffle", "Shuffle", shuffleDefault)
    p.addSwitch("twoTags", "Has 2+ tags", false)
    
    p.addButton("Load New", null, true)
    p.addButton("Update Previous")
    p.addButton("Show Previous")
    
    ///////////////////////////////
    
    if (p.show()) {
    
    const currentDraft = draft.uuid
    if (currentDraft !== pinnedDraft.uuid)
      editor.load(pinnedDraft)
    
    if (p.buttonPressed !== "Show Previous") {
    
    const tagSelected = p.fieldValues["tagPicker"]
    
    const reloadDrafts = body => {
      const firstLines = body.trim().split("\n\n").map(d => d.split("\n")[0].replace(/^\[\[/, "").replace(/\]\]$/, ""))
      return firstLines.map(l => Draft.queryByTitle(l).filter(d => d && d.uuid !== pinnedDraft.uuid)[0]).filter(d=>d)
    }
    
    let drafts = p.buttonPressed === "Update Previous"
      ? reloadDrafts(pinnedDraft.content.substring(pinnedDraft.content.indexOf("\n")+1))
      : Draft.query("", "all", [allowedTags[tagSelected]], omitTags).reverse()
    
    drafts = drafts.filter(d => d.uuid !== pinnedDraft.uuid)
    
    if (p.fieldValues["twoTags"])
      drafts = drafts.filter(d => d.tags.length >= 2)
    
    const count = p.fieldValues["count"] === "All"
      ? drafts.length : parseInt(p.fieldValues["count"])
    
    let keptDrafts = drafts
    let keptContent
    
    if (p.fieldValues["shuffle"])
      keptDrafts = keptDrafts.sort(()=>0.5-Math.random())
    
    keptDrafts = keptDrafts.slice(0, count)
    
    if (p.fieldValues["links"] === "UUID")
      keptContent = keptDrafts.map(d => `${d.content}\n- [[u:${d.uuid}]]`)
    else if (p.fieldValues["links"] === "Title")
      keptContent = keptDrafts.map(d => `[[${d.title}]]${d.processTemplate("[[body]]").length ? '\n' : ''}${d.processTemplate("[[body]]")}`)
    else 
      keptContent = keptDrafts.map(d => d.content)
    
    const title = p.buttonPressed === "Update Previous"
      ? pinnedDraft.title.replace(/\((\d+)\)/, `(${count})`)
      : `== ${allowedTags[tagSelected]} (${count})${p.fieldValues["twoTags"] ? ", 2+ tags" : ""}${p.fieldValues["shuffle"] ? ", shuffled" : ""} ==`
    
    editor.setText(title+"\n\n"+keptContent.join("\n\n"))
    
    pinnedDraft.versions.slice(keepVersions).forEach(v => v.delete())
    
    } // if (p.buttonPressed !== "Show Previous")
    
    } // if (p.show())
    
    if (device.model === "iPhone") app.hideActionList()

Options

  • After Success Nothing
    Notification Error
    Log Level Error
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.