/*eslint max-lines: ["warn", {"max": 350, "skipBlankLines": true, "skipComments": true}]*/ import './snippetbar.less'; import React, { useState, useEffect } from 'react'; import { Dropdown } from '@components/dropdown/dropdown.jsx'; import _ from 'lodash'; import cx from 'classnames'; import { loadHistory } from '../../utils/versionHistory.js'; import { brewSnippetsToJSON } from '@shared/helpers.js'; /*eslint-disable camelcase*/ import Legacy5ePHB from '@themes/Legacy/5ePHB/snippets.js'; import V3_5ePHB from '@themes/V3/5ePHB/snippets.js'; import V3_5eDMG from '@themes/V3/5eDMG/snippets.js'; import V3_Journal from '@themes/V3/Journal/snippets.js'; import V3_Blank from '@themes/V3/Blank/snippets.js'; const ThemeSnippets = { Legacy_5ePHB : Legacy5ePHB, V3_5ePHB : V3_5ePHB, V3_5eDMG : V3_5eDMG, V3_Journal : V3_Journal, V3_Blank : V3_Blank, }; /*eslint-enable camelcase */ const execute = function(val, props){ if(_.isFunction(val)) return val(props); return val; }; const SnippetBar = ({ brew = {}, view = 'text', onViewChange = ()=>{}, onInject = ()=>{}, onToggle = ()=>{}, showEditButtons = true, renderer = 'legacy', undo = ()=>{}, redo = ()=>{}, historySize = ()=>{}, foldCode = ()=>{}, unfoldCode = ()=>{}, formatCode = ()=>{}, cursorPos = {}, themeBundle = [], updateBrew = ()=>{} })=>{ const [snippets, setSnippets] = useState([]); const [historyExists, setHistoryExists] = useState(false); const [historyItems, setHistoryItems] = useState([]); useEffect(()=>{ setSnippets(compileSnippets()); }, []); const mergeCustomizer = (oldValue, newValue, key)=>{ if(key == 'snippets') { const result = _.reverse(_.unionBy(_.reverse(newValue), _.reverse(oldValue), 'name')); // Join snippets together, with preference for the child theme over the parent theme return result.filter((snip)=>snip.gen || snip.subsnippets); }; }; const compileSnippets = ()=>{ let compiledSnippets = []; let oldSnippets = _.keyBy(compiledSnippets, 'groupName'); if(themeBundle.snippets) { for (let snippets of themeBundle.snippets) { if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name snippets = ThemeSnippets[snippets]; const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName'); compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, mergeCustomizer)); oldSnippets = _.keyBy(compiledSnippets, 'groupName'); } } const userSnippetsasJSON = brewSnippetsToJSON(brew.title || 'New Document', brew.snippets, themeBundle.snippets); compiledSnippets.push(userSnippetsasJSON); return compiledSnippets; }; useEffect(()=>{ setSnippets(compileSnippets()); }, [renderer, themeBundle, brew.snippets]); useEffect(()=>{ const updateHistory = async ()=>{ // Update history list if it has changed const checkHistoryItems = await loadHistory(brew); // If all items have the noData property, there is no saved data const checkHistoryExists = !checkHistoryItems.every( (historyItem)=>historyItem?.noData ); if(historyExists !== checkHistoryExists) { setHistoryExists(checkHistoryExists); } // If any history items have changed, update the list if(!_.isEqual(checkHistoryItems, historyItems)) { setHistoryItems(checkHistoryItems); } }; updateHistory(); }, [brew]); const handleSnippetClick = (injectedText)=>onInject(injectedText); const renderSnippetGroups = ()=>{ const currentSnippets = snippets.filter((snippetGroup)=>snippetGroup.view === view); if(currentSnippets.length === 0) return null; return ; }; const replaceContent = (item)=>{ return updateBrew(item); }; const renderHistoryMenu = ()=>{ return ( } disabled={!historyExists} > {historyExists && _.map(historyItems, (item, index)=>{ if(item.noData || !item.savedAt) return null; const saveTime = new Date(item.savedAt); const diffMs = new Date() - saveTime; const diffSecs = Math.floor(diffMs / 1000); let diffString = `about ${diffSecs} seconds ago`; if(diffSecs > 60) diffString = `about ${Math.floor(diffSecs / 60)} minutes ago`; if(diffSecs > (60 * 60)) diffString = `about ${Math.floor(diffSecs / (60 * 60))} hours ago`; if(diffSecs > (24 * 60 * 60)) diffString = `about ${Math.floor(diffSecs / (24 * 60 * 60))} days ago`; if(diffSecs > (7 * 24 * 60 * 60)) diffString = `about ${Math.floor(diffSecs / (7 * 24 * 60 * 60))} weeks ago`; return (
  • ); })}
    ); }; const renderEditorButtons =()=>{ if(!showEditButtons) return; return (
    {view !== 'meta' && view !== 'settings' && <>
    {renderHistoryMenu()}
    }
    ); }; return
    {renderSnippetGroups()} {renderEditorButtons()}
    ; }; export default SnippetBar; const SnippetGroup = (props)=>{ const { brew = {}, groupName = '', icon = 'fas fa-rocket', snippets = [], onSnippetClick = function(){}, } = props; const handleSnippetClick = (e, snippet)=>{ onSnippetClick(execute(snippet.gen, props)); }; const renderSnippets = (snippets)=>{ return _.map(snippets, (snippet)=>{ if(!snippet.subsnippets){ return (
  • ); } else if(snippet.subsnippets){ return ( {renderSnippets(snippet.subsnippets)} ); } }); }; return {renderSnippets(snippets)} ; };