Action

Add to list plus

Posted by dchar, Last update about 3 years ago

UPDATES

about 3 years ago

V2021.09.13

  • Allow level 1 (#) or level 2 (##) category headings for list drafts.

  • Add option to configure the markdown header level of newly created lists.

  • Add option to configure the workspace tabs to search for lists.

Append to running lists in Drafts.

Action directory: https://actions.getdrafts.com/a/1Gd

Discuss in Drafts Forum

See it in action

This action is used to append items to running lists in Drafts. Useful for things like capturing movies you want to watch or stuff to pick up at the grocery store.

Based on an example action by @agiletortoise.

Usage

As a example, create a new list of movies to watch.

  • Create a new draft and enter Godfather
  • Tap the Add to list action
  • Press the button Create a new list
  • Enter Movies in the text field and press Ok

This creates a new draft with a title ## Movies and a tag lists:

## Movies

- [ ] Godfather

Add another movie.

  • Create a new draft and enter Jaws
  • Tap the Add to list action
  • Press the button Movies

This updates the movie list draft:

## Movies

- [ ] Godfather
- [ ] Jaws

These lists can be found by filtering the draft list by the tag lists. Create a Workspace for “Lists” with a tag filter for easy access.

Customizations

Several customizations are available in the first script action.

Change the variable appendItem to switch between append and prepend modes:

// true to append
// false to prepend
const appendItem = true;

Change the variable viewListAfterSuccess to load the list into the editor after the new list item has been successfully added.

Version History

V2021.09.13

  • Allow level 1 (#) or level 2 (##) category headings for list drafts.

  • Add option to configure the markdown header level of newly created lists.

  • Add option to configure the workspace tabs to search for lists.

Original

  • Add option to view list after success.

  • Look for lists in inbox, flagged, archive.

  • Add option to append or prepend items to a list.

  • Collect list names from tagged drafts.

  • Create new lists inside the action.

  • Based on an example action by @agiletortoise.

Steps

  • script

    // the tag used for list drafts
    const listTag = 'lists';
    
    // set this option to `true` to append
    // or `false` to prepend a new item.
    const appendItem = true;
    
    // set this option to `true` to view
    // the list after adding an item.
    const viewListAfterSuccess = false;
    
    // Set this option to configure the markdown
    // header level of a newly created list.
    //
    // The default ('##') matches the original
    // script from agiletortoise. Some may prefer
    // a level 1 markdown heading ('#') instead.
    const newListHeading = '##';
    
    // Set this option to configure the workspace
    // tabs to look for active lists.
    //
    // Some may prefer just inbox and flagged.
    const listWorkspaceTabs = ["inbox", "flagged", "archive"];
    
  • script

    // Add to list plus
    // Based on an example script from @agiletortoise
    //
    // v2021.09.13
    
    (() => {
    
    	const getLists = () => {
    		return listWorkspaceTabs
    			.map(s => Draft.query("", s, [listTag]))
    			.filter(arr => arr !== undefined)
    			.reduce((acc, v) => acc.concat(v), [])
    			.reduce((o, d) => {
    				const m = d.content.match(/#+ ([^\n]+)/);
    				if (m) { o[m[1].trim()] = d; }
    				return o;
    			}, {});
    	};
    
    	const sortcase = (xs) => {
    		return xs.sort((a,b) => {
    			return a.toLowerCase().localeCompare(b.toLowerCase());
    		})
    	}
    
    	const split = (s, delim) => {
    		const i = s.indexOf(delim);
    		return [
    			s.substr(0, (i>=0) ? i : s.length),
    			(i>=0) ? s.substr(i) : ''
    		]
    	};
    
    	const append = (s, item) => {
    		s = s.replace(/\n$/, '');
    		return [s, item].join('\n');
    	};
    
    	const prepend = (s, item) => {
    		const xs = split(s, '- [');
    		xs[0] = xs[0].replace(/\n$/, '');
    		return [xs[0], item, xs[1]].join('\n');
    	};
    
    	const main = () => {
    
    		if (draft.hasTag(listTag)) {
    			alert('Cannot run this action on a list draft.');
    			context.fail();
    			return;
    		}
    
    		// prompt to select a list
    		let p = Prompt.create();
    		p.title = 'Add item to list';
    
    		const lists = getLists();
    		sortcase(Object.keys(lists)).map(c => p.addButton(c));
    
    		// Give the user an option to create a new list
    		p.addButton('Create a new list');
    
    		if (!p.show()) {
    			context.fail();
    			return;
    		}
    
    		let d = lists[p.buttonPressed];
    		if (d === undefined) {
    			p = Prompt.create();
    			p.title = 'Create a new list';
    			p.addTextField('listName', 'List name', '');
    			p.addButton('Ok');
    
    			if (!p.show()) {
    				context.fail();
    				return;
    			}
    
    			const name = p.fieldValues['listName'].trim();
    			if (name.length == 0) {
    				alert('Invalid list name.');
    				context.fail();
    				return;
    			}
    
    			d = Draft.create();
    			d.content = newListHeading + ` ${name} \n\n`;
    			d.addTag(listTag);
    		}
    
    		const item = '- [ ] ' + draft.content.trim();
    		const fn = appendItem ? append : prepend;
    		d.content = fn(d.content, item);
    		d.update();
    
    		if (viewListAfterSuccess) {
    			editor.load(d);
    		}
    	};
    
    	main();
    
    })();
    

Options

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