dvargas92495 / SmartBlocks

Useful examples from developer community for Roam42 SmartBlocks
147 stars 7 forks source link

Iframe selector - choose iframe/Iframly, open in sidebar v1.3 #213

Open fbgallet opened 3 years ago

fbgallet commented 3 years ago

πŸ“Œ Import the JSON file below in your graph to be sure to preserve the code structure

iframe selector v1.3.zip

πŸ“‹ Description:

Demo video: https://youtu.be/ZqwE4hhpbVM

Open an iframe embed of an URL in child block (and optionally in sidebar), allowing to choose beetwen different Iframely views or iframe Roam vanilla (see video above for examples):

Default view is iframely default, as defined is [[roam/js/iframely]] settings. Other settings are available in the code block of the SmartBlock: force opening in sidebar, default string for the alias, default view, default css added to the iframe block.

v.1.3 May 23, 2021 New feature:

v1.1 March 27th 2021 Fixes:

βœ… Prerequisites or dependencies that are required for this SmartBlock

πŸ’‘ Additional Info

πŸ“Œ Import the JSON file below in your graph to be sure to preserve the code structure iframe selector v1.3.zip

βœ‚οΈ Code of the SmartBlock:

- #42SmartBlock iframe selector
    - <%JA:```javascript
/******************************************************************
                        iframe Selector
         Create {{iframe: }} or {{iframely: }} view in child block

Version: 1.3
Published: May 23, 2021
By: Fabrice Gallet
Twitter: @fbgallet

Support my work on: https://www.buymeacoffee.com/fbgallet

/************************* USER SETTINGS **************************/
let defaultMode = "iframely";        // change to "iframe" to create vanilla iframe by default
const iframeCSS = "#[[.iframe]]";    // change to "" for no CSS, or any other customized CSS
const aliasStr = "πŸ‘β€πŸ—¨ iframe";      // set alias for sneak peek in parent block
const withAlias = true;              // change to false if you don't want alias link to iframe block
let openInSideBar = false;           // change to true if you want, by default, opening the iframe in sidebar
/******************************************************************/

/* Function for extracting url from a text */
var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
function linkify(text) {
    return text.match(urlRegex);
} 

let dView = "default";
let pageUid = await roam42.common.getPageUidByTitle("roam/js/iframely");
let blockInfo = await roam42.common.getBlockInfoByUID(pageUid, true);
if (blockInfo !== null) {
  if (blockInfo[0][0].children) {
    if (blockInfo[0][0].children[0].children) {
        dView = blockInfo[0][0].children[0].children[0].string;      
    }
  }
}
const defaultView = dView;

var createIframeBlock = async function (parent, parentContent, link, mode, id, openSide) {
    let modeTab = mode.split(" ");
    mode = modeTab[0];
    let view = defaultView;
    if (modeTab.length > 1) { view = modeTab[1]; }

    window.roamAlphaAPI.updateBlock({"block": 
                {"uid": id,
                 "string": " ",
                 "open": false}});

    let iframeCommand = '{{' + mode + ': ' + link + '}} ' + iframeCSS;

    if ((modeTab.length > 1) && (view != "default")) {
        let currentBlockInfo = await roam42.common.getBlockInfoByUID(id, true);
        if (currentBlockInfo[0][0].children) {
            if (currentBlockInfo[0][0].children[0].string == "view") {
                  await roam42.common.updateBlock(currentBlockInfo[0][0].children[0].children[0].uid, view, true);
            }
          }
          else {
          await roam42.common.createBlock(id, -1, "view");
          let  childBlockInfo = await roam42.common.getBlockInfoByUID(id, true);
          await roam42.common.createBlock(childBlockInfo[0][0].children[0].uid, -1, view);
        }
    } else if ((mode == "iframe") || (view == "default")) {
      deleteChildBlocks(id);
    }  
    await roam42.common.sleep(50);
    window.roamAlphaAPI.updateBlock({"block": 
                {"uid": id,
                 "string": iframeCommand,
                 "open": false}});

    let blockPlusAliasToIframe = parentContent;
    if (withAlias && !existingIframe) {blockPlusAliasToIframe += " [" + aliasStr + "](((" + id + ")))";}

    if (openSide) {  
      if (fromParent) {
        window.roamAlphaAPI.updateBlock({"block": 
                  {"uid": parent,
                   "string": blockPlusAliasToIframe,
                   "open": false}});
      }

      window.roamAlphaAPI.ui.
        rightSidebar.addWindow({window:
            {type:'block' ,'block-uid': id}});
    } 
    else {
      if (fromParent) {
        window.roamAlphaAPI.updateBlock({"block": 
                  {"uid": parent,
                   "string": blockPlusAliasToIframe,
                   "open": true}});
      }
    }
}

var deleteChildBlocks = async function (id) {
    let currentBlockInfo = await roam42.common.getBlockInfoByUID(id, true);
    if (currentBlockInfo[0][0].children) {
        if (currentBlockInfo[0][0].children[0].string == "view") {
            await roam42.common.deleteBlock(currentBlockInfo[0][0].children[0].children[0].uid);
            await roam42.common.deleteBlock(currentBlockInfo[0][0].children[0].uid);  
        }
    }
}

/* Extract url from current block (there must not be more than one url in the block, otherwise the different urls are concatenated) */
let startingBlockUID = roam42.common.currentActiveBlockUID();
let iframeMode = defaultMode;
let uid = startingBlockUID;
let blockContent = document.activeElement.value;
blockContent = blockContent.trim();
let exist = false;
let fromChild = false;

if (blockContent=="") { blockContent = await navigator.clipboard.readText(); }
else if (blockContent.search("{{iframe") != -1) {
  fromChild = true;
  exist = true;}
else {
  let info = await roam42.common.getBlockInfoByUID(startingBlockUID, true);
  if (info[0][0].children) {
    let childContent = info[0][0].children[0].string;
     if (childContent.search("{{iframe") != -1) {
        exist = true;
        uid = info[0][0].children[0].uid;
     }
  }
}
const fromParent = !fromChild;
const existingIframe = exist;

let urlsTab = linkify(blockContent);
let url = urlsTab[urlsTab.length - 1];

if (!existingIframe) {
  uid = window.roamAlphaAPI.util.generateUID();
  window.roamAlphaAPI.createBlock(
        {"location": 
            {"parent-uid": startingBlockUID, 
              "order": 0},
          "block": 
            {"string": ' ',
             "uid": uid}});
}
createIframeBlock(startingBlockUID, blockContent, url, iframeMode, uid, false);

let checkState = '<input type="checkbox"';
if (openInSideBar) {checkState += ' checked="checked"';}
checkState += '>';

iziToast.info({
    resetOnHover: true,
    drag: false,
    close: false,
    overlay: false,
    position: "center",
    title: 'Iframe selector',
    message: 'Open in sidebar ?',
    inputs: [
        [checkState, 'change', function (instance, toast, input, e) {
//            console.log(input.checked);
        }],
        ['<select><option value="iframely default">Default Iframely</option><option value="iframe">Vanilla iframe</option><option value="iframely summary">Iframely summary</option><option value="iframely card">Iframely card</option><option value="iframely iframe">Iframely iframe</option></select>', 'change', function (instance, toast, select, e) {
          createIframeBlock(startingBlockUID, blockContent, url, select.options[select.selectedIndex].value, uid, false);
        }, true]
    ],
    buttons: [
        ['<button><b>Confirm</b></button>', function (instance, toast, button, e, inputs) {
//            console.log('Second field: ' + inputs[2].options[inputs[2].selectedIndex].value);           
//            iframeMode = inputs[1].options[inputs[1].selectedIndex].value;
            if (inputs[0].checked) {
              createIframeBlock(startingBlockUID, blockContent, url, iframeMode, uid, inputs[0].checked);
            }
            instance.hide({ transitionOut: 'fadeOut' }, toast, 'button');
        }, false],
        ['<button><b>Cancel</b></button>', function (instance, toast, button, e, inputs) {
             if (!existingIframe) { 
               window.roamAlphaAPI.updateBlock({"block": 
                  {"uid": startingBlockUID,
                   "string": blockContent
                  }});
                deleteChildBlocks(uid);
                roam42.common.deleteBlock(uid);
              }
              instance.hide({ transitionOut: 'fadeOut' }, toast, 'button');
        }, false],
    ],
   onClosing: function(instance, toast, closedBy){
        },
        onClosed: function(instance, toast, closedBy){
        }
}); 
```%> <%NOBLOCKOUTPUT%>
- <%JA:```javascript
/******************************************************************
                        iframe Selector
         Create {{iframe: }} or {{iframely: }} view in child block

Version: 1.3
Published: May 23, 2021
By: Fabrice Gallet
Twitter: @fbgallet

Support my work on: https://www.buymeacoffee.com/fbgallet

/************************* USER SETTINGS **************************/
let defaultMode = "iframely";        // change to "iframe" to create vanilla iframe by default
const iframeCSS = "#[[.iframe]]";    // change to "" for no CSS, or any other customized CSS
const aliasStr = "πŸ‘β€πŸ—¨ iframe";      // set alias for sneak peek in parent block
const withAlias = true;              // change to false if you don't want alias link to iframe block
let openInSideBar = false;           // change to true if you want, by default, opening the iframe in sidebar
/******************************************************************/

/* Function for extracting url from a text */
var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
function linkify(text) {
    return text.match(urlRegex);
} 

let dView = "default";
let pageUid = await roam42.common.getPageUidByTitle("roam/js/iframely");
let blockInfo = await roam42.common.getBlockInfoByUID(pageUid, true);
if (blockInfo !== null) {
  if (blockInfo[0][0].children) {
    if (blockInfo[0][0].children[0].children) {
        dView = blockInfo[0][0].children[0].children[0].string;      
    }
  }
}
const defaultView = dView;

var createIframeBlock = async function (parent, parentContent, link, mode, id, openSide) {
    let modeTab = mode.split(" ");
    mode = modeTab[0];
    let view = defaultView;
    if (modeTab.length > 1) { view = modeTab[1]; }

    window.roamAlphaAPI.updateBlock({"block": 
                {"uid": id,
                 "string": " ",
                 "open": false}});

    let iframeCommand = '{{' + mode + ': ' + link + '}} ' + iframeCSS;

    if ((modeTab.length > 1) && (view != "default")) {
        let currentBlockInfo = await roam42.common.getBlockInfoByUID(id, true);
        if (currentBlockInfo[0][0].children) {
            if (currentBlockInfo[0][0].children[0].string == "view") {
                  await roam42.common.updateBlock(currentBlockInfo[0][0].children[0].children[0].uid, view, true);
            }
          }
          else {
          await roam42.common.createBlock(id, -1, "view");
          let  childBlockInfo = await roam42.common.getBlockInfoByUID(id, true);
          await roam42.common.createBlock(childBlockInfo[0][0].children[0].uid, -1, view);
        }
    } else if ((mode == "iframe") || (view == "default")) {
      deleteChildBlocks(id);
    }  
    await roam42.common.sleep(50);
    window.roamAlphaAPI.updateBlock({"block": 
                {"uid": id,
                 "string": iframeCommand,
                 "open": false}});

    let blockPlusAliasToIframe = parentContent;
    if (withAlias && !existingIframe) {blockPlusAliasToIframe += " [" + aliasStr + "](((" + id + ")))";}

    if (openSide) {  
      if (fromParent) {
        window.roamAlphaAPI.updateBlock({"block": 
                  {"uid": parent,
                   "string": blockPlusAliasToIframe,
                   "open": false}});
      }

      window.roamAlphaAPI.ui.
        rightSidebar.addWindow({window:
            {type:'block' ,'block-uid': id}});
    } 
    else {
      if (fromParent) {
        window.roamAlphaAPI.updateBlock({"block": 
                  {"uid": parent,
                   "string": blockPlusAliasToIframe,
                   "open": true}});
      }
    }
}

var deleteChildBlocks = async function (id) {
    let currentBlockInfo = await roam42.common.getBlockInfoByUID(id, true);
    if (currentBlockInfo[0][0].children) {
        if (currentBlockInfo[0][0].children[0].string == "view") {
            await roam42.common.deleteBlock(currentBlockInfo[0][0].children[0].children[0].uid);
            await roam42.common.deleteBlock(currentBlockInfo[0][0].children[0].uid);  
        }
    }
}

/* Extract url from current block (there must not be more than one url in the block, otherwise the different urls are concatenated) */
let startingBlockUID = roam42.common.currentActiveBlockUID();
let iframeMode = defaultMode;
let uid = startingBlockUID;
let blockContent = document.activeElement.value;
blockContent = blockContent.trim();
let exist = false;
let fromChild = false;

if (blockContent=="") { blockContent = await navigator.clipboard.readText(); }
else if (blockContent.search("{{iframe") != -1) {
  fromChild = true;
  exist = true;}
else {
  let info = await roam42.common.getBlockInfoByUID(startingBlockUID, true);
  if (info[0][0].children) {
    let childContent = info[0][0].children[0].string;
     if (childContent.search("{{iframe") != -1) {
        exist = true;
        uid = info[0][0].children[0].uid;
     }
  }
}
const fromParent = !fromChild;
const existingIframe = exist;

let urlsTab = linkify(blockContent);
let url = urlsTab[urlsTab.length - 1];

if (!existingIframe) {
  uid = window.roamAlphaAPI.util.generateUID();
  window.roamAlphaAPI.createBlock(
        {"location": 
            {"parent-uid": startingBlockUID, 
              "order": 0},
          "block": 
            {"string": ' ',
             "uid": uid}});
}
createIframeBlock(startingBlockUID, blockContent, url, iframeMode, uid, false);

let checkState = '<input type="checkbox"';
if (openInSideBar) {checkState += ' checked="checked"';}
checkState += '>';

iziToast.info({
    resetOnHover: true,
    drag: false,
    close: false,
    overlay: false,
    position: "center",
    title: 'Iframe selector',
    message: 'Open in sidebar ?',
    inputs: [
        [checkState, 'change', function (instance, toast, input, e) {
//            console.log(input.checked);
        }],
        ['<select><option value="iframely default">Default Iframely</option><option value="iframe">Vanilla iframe</option><option value="iframely summary">Iframely summary</option><option value="iframely card">Iframely card</option><option value="iframely iframe">Iframely iframe</option></select>', 'change', function (instance, toast, select, e) {
          createIframeBlock(startingBlockUID, blockContent, url, select.options[select.selectedIndex].value, uid, false);
        }, true]
    ],
    buttons: [
        ['<button><b>Confirm</b></button>', function (instance, toast, button, e, inputs) {
//            console.log('Second field: ' + inputs[2].options[inputs[2].selectedIndex].value);           
//            iframeMode = inputs[1].options[inputs[1].selectedIndex].value;
            if (inputs[0].checked) {
              createIframeBlock(startingBlockUID, blockContent, url, iframeMode, uid, inputs[0].checked);
            }
            instance.hide({ transitionOut: 'fadeOut' }, toast, 'button');
        }, false],
        ['<button><b>Cancel</b></button>', function (instance, toast, button, e, inputs) {
             if (!existingIframe) { 
               window.roamAlphaAPI.updateBlock({"block": 
                  {"uid": startingBlockUID,
                   "string": blockContent
                  }});
                deleteChildBlocks(uid);
                roam42.common.deleteBlock(uid);
              }
              instance.hide({ transitionOut: 'fadeOut' }, toast, 'button');
        }, false],
    ],
   onClosing: function(instance, toast, closedBy){
        },
        onClosed: function(instance, toast, closedBy){
        }
}); 
```%> <%NOBLOCKOUTPUT%>

πŸ“· Screenshot of the #42SmartBlock (note entire code)

image)

kmaustral commented 3 years ago

Thank you (merci) Fabrice. This looks very useful. When I run it, I get the iframe but it doesn't open in the sidebar.

This is what I get in the sidebar: '--> Variable iframeRef not SET <--'

fbgallet commented 3 years ago

Hi @kmaustral , make sure that the two smartblock commands beetwen the two blocks of javascript are on their own line:

If it doesn't work, add perhaps some sleep time at the end of first javascript block.

fbgallet commented 3 years ago

I have added a link to the JSON file for better support of the code structure.

kmaustral commented 3 years ago

Thanks. It works fine now. It seems like Roam is becoming more and more like a browser.

fbgallet commented 3 years ago

New version, v1.1, with some fixes has been pushed up