import joplin from 'api' ; import { MenuItem , MenuItemLocation } from 'api/types' ; import { ChangeEvent } from 'api/JoplinSettings' ; import { FavoriteType , IFavorite , Favorites } from './favorites' ; import { Settings } from './settings' ; import { Panel } from './panel' ; import { Dialog } from './dialog' ; joplin . plugins . register ( { onStart : async function ( ) { const CLIPBOARD = joplin . clipboard ; const COMMANDS = joplin . commands ; const DATA = joplin . data ; const SETTINGS = joplin . settings ; const WORKSPACE = joplin . workspace ; const settings = new Settings ( ) ; await settings . register ( ) ; const favorites = new Favorites ( settings ) ; const panel = new Panel ( favorites , settings ) ; await panel . register ( ) ; const addDialog = new Dialog ( 'Add' ) ; await addDialog . register ( ) ; const editDialog = new Dialog ( 'Edit' ) ; await editDialog . register ( [ { id : 'delete' , title : 'Delete' , } , { id : 'ok' , title : 'OK' } , { id : 'cancel' , title : 'Cancel' } ] ) ; /**
         * Check if favorite target still exists - otherwise ask to remove favorite
         */ async function checkAndRemoveFavorite ( favorite , index ) { try { await DATA . get ( [ Favorites . getDesc ( favorite ) . dataType , favorite . value ] , { fields : [ 'id' ] } ) ; } catch ( err ) { const result = await Dialog . showMessage ( `Cannot open favorite. Seems that the target ${ Favorites . getDesc ( favorite ) . name . toLocaleLowerCase ( ) } was deleted.\n\nDo you want to delete the favorite also?` ) ; if ( ! result ) { await favorites . delete ( index ) ; await panel . updateWebview ( ) ; return true ; } } return false ; } /**
         * Check if note/todo is still of the same type - otherwise change type
         */ async function checkAndUpdateType ( favorite , index ) { let newType ; const note = await DATA . get ( [ Favorites . getDesc ( favorite ) . dataType , favorite . value ] , { fields : [ 'id' , 'is_todo' ] } ) ; if ( Favorites . isNote ( favorite ) && note . is_todo ) newType = FavoriteType . Todo ; if ( Favorites . isTodo ( favorite ) && ( ! note . is_todo ) ) newType = FavoriteType . Note ; if ( newType ) { await favorites . changeType ( index , newType ) ; await panel . updateWebview ( ) ; } } /**
         * Add new favorite entry
         */ async function addFavorite ( value , title , type , showDialog , targetIdx ? ) { let newValue = value ; let newTitle = title ; const index = favorites . indexOf ( value ) ; if ( index >= 0 ) { await COMMANDS . execute ( 'favsEditFavorite' , index ) ; } else { if ( showDialog ) { const result = await addDialog . open ( favorites . create ( newValue , newTitle , type ) ) ; if ( result . id == 'ok' && result . formData != null ) { newTitle = result . formData . inputForm . title ; if ( result . formData . inputForm . value ) newValue = result . formData . inputForm . value ; } else return ; } if ( newValue === '' || newTitle === '' ) return ; await favorites . add ( newValue , newTitle , type , targetIdx ) ; await panel . updateWebview ( ) ; } } await COMMANDS . register ( { name : 'favsOpenFavorite' , execute : async ( index ) => { const favorite = favorites . get ( index ) ; if ( ! favorite ) return ; switch ( favorite . type ) { case FavoriteType . Folder : if ( await checkAndRemoveFavorite ( favorite , index ) ) return ; COMMANDS . execute ( 'openFolder' , favorite . value ) ; break ; case FavoriteType . Note : case FavoriteType . Todo : if ( await checkAndRemoveFavorite ( favorite , index ) ) return ; await checkAndUpdateType ( favorite , index ) ; COMMANDS . execute ( 'openNote' , favorite . value ) ; break ; case FavoriteType . Tag : if ( await checkAndRemoveFavorite ( favorite , index ) ) return ; COMMANDS . execute ( 'openTag' , favorite . value ) ; break ; case FavoriteType . Search : await CLIPBOARD . writeText ( favorites . getDecodedValue ( favorite ) ) ; await COMMANDS . execute ( 'focusSearch' ) ; break ; default : break ; } await panel . updateWebview ( ) ; } } ) ; await COMMANDS . register ( { name : 'favsEditFavorite' , execute : async ( index ) => { const favorite = favorites . get ( index ) ; if ( ! favorite ) return ; const result = await editDialog . open ( favorite ) ; if ( result . id == "ok" && result . formData != null ) { await favorites . changeTitle ( index , result . formData . inputForm . title ) ; await favorites . changeValue ( index , result . formData . inputForm . value ) ; } else if ( result . id == "delete" ) { await favorites . delete ( index ) ; } else { return ; } await panel . updateWebview ( ) ; } } ) ; await COMMANDS . register ( { name : 'favsAddFolder' , label : 'Add notebook to Favorites' , iconName : 'fas fa-book' , enabledCondition : 'oneFolderSelected' , execute : async ( folderId , targetIdx ? ) => { if ( folderId ) { const folder = await DATA . get ( [ 'folders' , folderId ] , { fields : [ 'id' , 'title' ] } ) ; if ( ! folder ) return ; await addFavorite ( folder . id , folder . title , FavoriteType . Folder , settings . editBeforeAdd , targetIdx ) ; } else { const selectedFolder = await WORKSPACE . selectedFolder ( ) ; if ( ! selectedFolder ) return ; await addFavorite ( selectedFolder . id , selectedFolder . title , FavoriteType . Folder , settings . editBeforeAdd , targetIdx ) ; } } } ) ; await COMMANDS . register ( { name : 'favsAddNote' , label : 'Add note to Favorites' , iconName : 'fas fa-sticky-note' , enabledCondition : "someNotesSelected" , execute : async ( noteIds , targetIdx ? ) => { if ( noteIds ) { for ( const noteId of noteIds ) { if ( noteIds . length > 1 && favorites . hasFavorite ( noteId ) ) continue ; const note = await DATA . get ( [ 'notes' , noteId ] , { fields : [ 'id' , 'title' , 'is_todo' ] } ) ; if ( ! note ) return ; const showDialog = ( settings . editBeforeAdd && noteIds . length == 1 ) ; await addFavorite ( note . id , note . title , note . is_todo ? FavoriteType . Todo : FavoriteType . Note , showDialog , targetIdx ) ; } } else { const selectedNote = await WORKSPACE . selectedNote ( ) ; if ( ! selectedNote ) return ; await addFavorite ( selectedNote . id , selectedNote . title , selectedNote . is_todo ? FavoriteType . Todo : FavoriteType . Note , settings . editBeforeAdd , targetIdx ) ; } } } ) ; await COMMANDS . register ( { name : 'favsAddTag' , label : 'Add tag to Favorites' , iconName : 'fas fa-tag' , execute : async ( tagId ) => { if ( tagId ) { const tag = await DATA . get ( [ 'tags' , tagId ] , { fields : [ 'id' , 'title' ] } ) ; if ( ! tag ) return ; await addFavorite ( tag . id , tag . title , FavoriteType . Tag , settings . editBeforeAdd ) ; } } } ) ; await COMMANDS . register ( { name : 'favsAddSearch' , label : 'Add new search to Favorites' , iconName : 'fas fa-search' , execute : async ( ) => { await addFavorite ( '' , 'New Search' , FavoriteType . Search , true ) ; } } ) ; await COMMANDS . register ( { name : 'favsClear' , label : 'Remove all Favorites' , iconName : 'fas fa-times' , execute : async ( ) => { const result = await Dialog . showMessage ( 'Do you really want to remove all Favorites?' ) ; if ( result ) return ; await settings . clearFavorites ( ) ; await panel . updateWebview ( ) ; } } ) ; await COMMANDS . register ( { name : 'favsToggleVisibility' , label : 'Toggle Favorites visibility' , iconName : 'fas fa-eye-slash' , execute : async ( ) => { await panel . toggleVisibility ( ) ; } } ) ; const commandsSubMenu = [ { commandName : 'favsAddFolder' , label : 'Add active notebook' } , { commandName : 'favsAddNote' , label : 'Add selected note(s)' } , { commandName : 'favsAddSearch' , label : 'Add new search' } , { commandName : 'favsClear' , label : 'Remove all Favorites' } , { commandName : 'favsToggleVisibility' , label : 'Toggle panel visibility' } ] ; await joplin . views . menus . create ( 'toolsFavorites' , 'Favorites' , commandsSubMenu , MenuItemLocation . Tools ) ; await joplin . views . menuItems . create ( 'foldersContextMenuAddFolder' , 'favsAddFolder' , MenuItemLocation . FolderContextMenu ) ; await joplin . views . menuItems . create ( 'tagsContextMenuAddNote' , 'favsAddTag' , MenuItemLocation . TagContextMenu ) ; await joplin . views . menuItems . create ( 'notesContextMenuAddNote' , 'favsAddNote' , MenuItemLocation . NoteListContextMenu ) ; await joplin . views . menuItems . create ( 'editorContextMenuAddNote' , 'favsAddNote' , MenuItemLocation . EditorContextMenu ) ; SETTINGS . onChange ( async ( event ) => { await settings . read ( event ) ; await panel . updateWebview ( ) ; } ) ; await panel . updateWebview ( ) ; } } ) ;