Action

QuickLink Opener

Posted by FlohGro, Last update about 2 months ago - Unlisted

created by @FlohGro / more on my Blog

Quickly open a link from a configurable list in a draft.
When you first run the action it will create a draft with the title QuickLink Opener Configuration Draft and an example configuration.

Adapt the defined categories and links to your preference. A category is defined by an H2 markdown header (prefixed with “##”). Every url in that section belongs to that category.

URLs have to be formatted as markdown urls ([title](url)).

You can define any number of categories and urls inside them.

When you run the action it will first display a prompt, where you can select the category of the link you want to open. After selecting a category it will display all found urls of that section and open the selected url.

If you want to change the configured urls you can run this action and select the first option open configuration draft.

The initial example will look like this - it contains two categories each with a single url configured.

# QuickLink Opener Configuration Draft

## Example Link Category 1

- [Drafts](https://getdrafts.com)

## Example Link Category 2

- [FlohGro's Blog](https://flohgro.com)

In case you want to change the default title of the configuration draft, just edit the action and type your desired name into the content field of the available template tag configuration_draft_title (do not change the name of the template tag, only its content)

If you find this useful and want to support me you can donate or buy me a coffee

Buy Me a Coffee at ko-fi.com Trusted member

Steps

  • defineTemplateTag

    name
    configuration_draft_title
    template
  • script

    // quick link opener v1.0
    // created by FlohGro
    
    const defaultConfigurationDraftTitle = "QuickLink Opener Configuration Draft"
    const userConfiguredDraftTitle = draft.processTemplate("[[configuration_draft_title]]")
    
    const configurationDraftTitle = (userConfiguredDraftTitle != "" && userConfiguredDraftTitle != "[[configuration_draft_title]]") ? userConfiguredDraftTitle : defaultConfigurationDraftTitle
    
    let foundDraft = Draft.queryByTitle(configurationDraftTitle)
    
    if (foundDraft.length == 0) {
        // the configuration draft is currently not existing, we need to create it for the user so that he/she can configure it later
        createDraftAndCancel()
    } else if (foundDraft.length > 1) {
        // there are several drafts with the specified title. The user needs to cleanup the mess to run this again.
        console.log("more than one configuration drafts with title: " + configurationDraftTitle + " exist")
        alert("more than one configuration drafts with title: " + configurationDraftTitle + " exist\n\nplease clean up the mess (merge these two Drafts and run the action again")
        context.cancel()
    } else {
        // the configuration draft draft exists, which is great. We can work with that
    
        let sectionToUse = findSectionToUse(foundDraft[0]);
    
        if (sectionToUse) {
            if (sectionToUse == "open configuration draft") {
                editor.load(foundDraft[0])
            } else {
                let urlToOpen = getLinkToOpen(sectionToUse)
                if (urlToOpen) {
                    app.openURL(urlToOpen, true)
                }
            }
        }
    }
    
    function createDraftAndCancel() {
        let newDraft = new Draft()
        newDraft.content = `# ${configurationDraftTitle}
    
    ## Example Link Category 1
    
    - [Drafts](https://getdrafts.com)
    
    ## Example Link Category 2
    
    - [FlohGro's Blog](https://flohgro.com)
    
    `
        newDraft.update()
    
        console.log("created configuration draft with title: " + configurationDraftTitle + " since it was not existing")
    
        alert("created configuration draft with title: " + configurationDraftTitle + " since it was not existing\n\nplease configure it according to the actiondescription and run the action again")
        editor.load(newDraft)
        context.cancel()
    }
    
    
    function splitMarkdownSections(text) {
        const sections = new Map()
        const splits = text.split('##');
        let currentSection = '';
        splits.shift()
    
        for (let split of splits) {
            let lines = split.split("\n")
            let firstLine = lines.shift()
            sections.set(firstLine, lines.join("\n"))
        }
        return sections;
    }
    
    function findSectionToUse(theDraft) {
    
        let map = splitMarkdownSections(theDraft.content)
    
        if (map.size == 0) {
            return theDraft.content
        } else if (map.size == 1) {
            return map.get(map.keys()[0])
        } else {
            let p = new Prompt()
            p.title = "select category"
    
            p.addButton("open configuration draft")
            Array.from(map.keys()).forEach((key) => {
                p.addButton(key, map.get(key))
            })
    
            if (p.show()) {
                return p.buttonPressed
            } else {
                showCancelledMessage()
                return undefined
            }
        }
    
    }
    
    function getLinkToOpen(text) {
    
        let p = new Prompt()
    
        p.title = "open which link?"
    
        //const regex = /\[(.+)\]\(craftdocs:\/\/open\?blockId=([^&]+)\&spaceId=([^\)]+)\)/
        const regex = /\[([^\[]+)\]\(([^\[^\n]+)\)/g
        let foundUrlCounter = 0;
    
        var matches = [...text.matchAll(regex)]
        if (matches) {
            for (match of matches) {
                foundUrlCounter++;
                let description = match[1];
                let url = match[2];
                // add "https://" if the url is no callback url and just witten as domain.
                if (!url.match(/:\/\//)) {
                    url = 'https://' + url;
                }
                // add the found url to the prompt
                p.addButton(description, url);
                if (foundUrlCounter == 1) {
                    firstURL = url;
                }
            }
        }
    
        if (foundUrlCounter == 0) {
            app.displayWarningMessage("no urls found")
            return undefined;
        } else if (p.show()) {
            return p.buttonPressed
        } else {
            showCancelledMessage()
            return undefined;
        }
    
    }
    
    function showCancelledMessage() {
        app.displayInfoMessage("cancelled")
    }
    

Options

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