Action

Diff Versions

Posted by agiletortoise, Last update 10 months ago

Note: The Mergely library on which this action is based is not optimized for use on smaller screens. As such, this action is best used on Mac - although it can be used on iPad, or even iPhone, it is a less than optimal experience.

Open a diffing tool to compare and merge values from the current draft’s version history.

Once opened, you can select from the past draft versions in the drop-down menu. Changes will be displayed and can be merged between the versions.

Once you are satisfied with the changes, you can save either version as the current version of the draft - or discard changes.

This action utilizes the Mergely diffing tool.

Steps

  • script

    // gathers a list of past versions of the draft currently loaded in the editor
    
    let f = () => {
    	let versions = draft.versions
    
    	if (versions.length == 0) {
    		alert("The current draft has no past versions in the version history. This action requires a version history to show differences.")
    		return false
    	}
    
    	let sources = [
    		{
    			"name": "Current",
    			"value": draft.content
    		}
    	]
    	for (let v of versions) {
    		sources.push({
    			"name": `V: ${strftime(v.createdAt, "%Y-%m-%d %H:%M")}, ${v.content.length} char`,
    			"value": v.content
    		})
    	}
    
    	draft.setTemplateTag("sources", JSON.stringify(sources))
    	return true
    }
    
    if (!f()) {
    	context.cancel()
    }
  • htmlpreview

    <html>
    
    <head>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mergely/5.0.0/mergely.min.js"></script>
        <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mergely/5.0.0/mergely.css" />
        <style>
            body {
                height: 100%;
                margin: 0;
            }
    
            .box {
                display: flex;
                flex-direction: column;
                height: 100%;
                width: 100%;
            }
    
            .row {
                flex: 0 0 auto;
                border: 1px solid #ddd;
            }
    
            .row.expand {
                overflow: auto;
                flex: 1 1 auto;
            }
    
            #top-toolbar {
                padding: 1em;
                text-align: center;
            }
    
            #bottom-toolbar {
                padding: 1em;
                text-align: center;
            }
    
            .source {
                font-size: 1.1em;
                font-weight: bold;
                max-width: 40%;
            }
    
            .source option {
                font-weight: bold;
            }
    
            textarea {
                font-size: 1.5em;
            }
    
            .button-toolbar {
                appearance: none;
                background-color: #2ea44f;
                border: 1px solid rgba(27, 31, 35, .15);
                border-radius: 6px;
                box-shadow: rgba(27, 31, 35, .1) 0 1px 0;
                box-sizing: border-box;
                color: #fff;
                cursor: pointer;
                display: inline-block;
                font-family: -apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
                font-size: 14px;
                font-weight: 600;
                line-height: 20px;
                padding: 6px 16px;
                position: relative;
                text-align: center;
                text-decoration: none;
                user-select: none;
                -webkit-user-select: none;
                touch-action: manipulation;
                vertical-align: middle;
                white-space: nowrap;
                margin: 0 2em 0 2em;
            }
    
            .gray {
                background-color: #666666;
            }
    
            .CodeMirror-code,
    #mergely .CodeMirror-lines pre, 
    #mergely .CodeMirror-gutter-text pre {
      font-size: 1rem !important;
      line-height: 1.5 !important;
      color: #000 !important;
    }
        </style>
    </head>
    
    <body>
        <div class="box">
            <div id="top-toolbar" class="row">
                <form onsubmit="return false;">
                    <select name="lhs" id="lhs" onchange="updateLeft()" class="source">
                    </select>
                    &nbsp; &lt;&nbsp;&gt;&nbsp;
                    <select name="rhs" id="rhs" onchange="updateRight()" class="source">
                    </select>
                </form>
            </div>
    
            <div id="compare" class="row expand"></div>
    
            <div id="bottom-toolbar" class="row">
                <button class="button-toolbar" onclick="commitLeft();return false;">Save Left</button>
                <button class="button-toolbar gray" onclick="discardChanges();return false;">Discard Changes</button>
                <button class="button-toolbar" onclick="commitRight();return false;">Save Right</button>
            </div>
    
        </div>
    
        <script>
            const sources = JSON.parse('{{javascriptEscape(sources)}}')
            const doc = new Mergely('#compare', {
                "wrap_lines": true,
                "viewport": false,
                "cmsettings": {
    
                }
            });
            doc.once('updated', () => {
                doc.lhs('');
                doc.rhs('');
                // Scroll to first change on next update
                doc.once('updated', () => {
                    doc.scrollToDiff('next');
                });
    
                let lhsSelect = document.getElementById("lhs")
                sources.forEach(function (elem) {
                    let op = document.createElement("option")
                    op.value = elem.value
                    op.text = elem.name
                    lhsSelect.add(op)
                })
    
                let rhsSelect = document.getElementById("rhs")
                sources.forEach(function (elem) {
                    let op = document.createElement("option")
                    op.value = elem.value
                    op.text = elem.name
                    rhsSelect.add(op)
                })
                rhsSelect.options.selectedIndex = 1
                updateLeft()
                updateRight()
            });
    
            function updateLeft() {
                let lhsSelect = document.getElementById("lhs")
                doc.lhs(lhsSelect.value)
            }
            function updateRight() {
                let rhsSelect = document.getElementById("rhs")
                doc.rhs(rhsSelect.value)
            }
    
            function commitLeft() {
                Drafts.send("result", doc.get('lhs'))
                Drafts.continue()
            }
            function commitRight() {
                Drafts.send("result", doc.get('rhs'))
                Drafts.continue()
            }
            function discardChanges() {
                Drafts.cancel()
            }
        </script>
    </body>
    
    </html>
  • script

    // get the merged text and update the editor
    let result = context.previewValues["result"]
    editor.setText(result)
    

Options

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