@ -297,7 +297,7 @@ export default {
}
} ,
created ( ) {
this . $bus . $on ( 'write_local_file' , this . onWriteLocalFile )
/ / t h i s . $ b u s . $ o n ( ' w r i t e _ l o c a l _ f i l e ' , t h i s . o n W r i t e L o c a l F i l e )
} ,
mounted ( ) {
this . computeToolbarShow ( )
@ -309,7 +309,7 @@ export default {
} ,
beforeDestroy ( ) {
this . $bus . $off ( 'write_local_file' , this . onWriteLocalFile )
/ / t h i s . $ b u s . $ o f f ( ' w r i t e _ l o c a l _ f i l e ' , t h i s . o n W r i t e L o c a l F i l e )
window . removeEventListener ( 'resize' , this . computeToolbarShowThrottle )
this . $bus . $off ( 'lang_change' , this . computeToolbarShowThrottle )
window . removeEventListener ( 'beforeunload' , this . onUnload )
@ -343,219 +343,196 @@ export default {
} ,
/ / 监 听 本 地 文 件 读 写
onWriteLocalFile ( content ) {
clearTimeout ( this . timer )
if ( fileHandle && this . isHandleLocalFile ) {
this . waitingWriteToLocalFile = tru e
}
this . timer = setTimeout ( ( ) => {
this . writeLocalFile ( content )
} , 1000 )
} ,
/ / o n W r i t e L o c a l F i l e ( c o n t e n t ) {
/ / c l e a r T i m e o u t ( t h i s . t i m e r )
/ / i f ( f i l e H a n d l e & & t h i s . i s H a n d l e L o c a l F i l e ) {
/ / t h i s . w a i t i n g W r i t e T o L o c a l F i l e = t r u e
/ / }
/ / t h i s . t i m e r = s e t T i m e o u t ( ( ) = > {
/ / t h i s . w r i t e L o c a l F i l e ( c o n t e n t )
/ / } , 1 0 0 0 )
/ / } ,
onUnload ( e ) {
if ( this . waitingWriteToLocalFile ) {
const msg = '存在未保存的数据 '
e . returnValue = ms g
return ms g
}
/ / i f ( t h i s . w a i t i n g W r i t e T o L o c a l F i l e ) {
/ / c o n s t m s g = ' 存 在 未 保 存 的 数 据 '
/ / e . r e t u r n V a l u e = m s g
/ / r e t u r n m s g
/ / }
} ,
/ / 加 载 本 地 文 件 树
async loadFileTreeNode ( node , resolve ) {
try {
let dirHandl e
if ( node . level === 0 ) {
dirHandle = await window . showDirectoryPicker ( )
this . rootDirName = dirHandle . nam e
} else {
dirHandle = node . data . handl e
}
const dirList = [ ]
const fileList = [ ]
for await ( const [ key , value ] of dirHandle . entries ( ) ) {
const isFile = value . kind === 'file '
if ( isFile && ! /\.(smm|xmind|md|json)$/ . test ( value . name ) ) {
continu e
}
const enableEdit = isFile && /\.smm$/ . test ( value . name )
const data = {
id : key ,
name : value . name ,
type : value . kind ,
handle : value ,
leaf : isFile ,
enableEdi t
}
if ( isFile ) {
fileList . push ( data )
} else {
dirList . push ( data )
}
}
resolve ( [ ... dirList , ... fileList ] )
} catch ( error ) {
console . log ( error )
this . fileTreeVisible = fals e
resolve ( [ ] )
if ( error . toString ( ) . includes ( 'aborted' ) ) {
retur n
}
this . $message . warning ( this . $t ( 'toolbar.notSupportTip' ) )
}
} ,
/ / a s y n c l o a d F i l e T r e e N o d e ( n o d e , r e s o l v e ) {
/ / t r y {
/ / l e t d i r H a n d l e
/ / i f ( n o d e . l e v e l = = = 0 ) {
/ / d i r H a n d l e = a w a i t w i n d o w . s h o w D i r e c t o r y P i c k e r ( )
/ / t h i s . r o o t D i r N a m e = d i r H a n d l e . n a m e
/ / } e l s e {
/ / d i r H a n d l e = n o d e . d a t a . h a n d l e
/ / }
/ / c o n s t d i r L i s t = [ ]
/ / c o n s t f i l e L i s t = [ ]
/ / f o r a w a i t ( c o n s t [ k e y , v a l u e ] o f d i r H a n d l e . e n t r i e s ( ) ) {
/ / c o n s t i s F i l e = v a l u e . k i n d = = = ' f i l e '
/ / i f ( i s F i l e & & ! / \ . ( s m m | x m i n d | m d | j s o n ) $ / . t e s t ( v a l u e . n a m e ) ) {
/ / c o n t i n u e
/ / }
/ / c o n s t e n a b l e E d i t = i s F i l e & & / \ . s m m $ / . t e s t ( v a l u e . n a m e )
/ / c o n s t d a t a = {
/ / i d : k e y ,
/ / n a m e : v a l u e . n a m e ,
/ / t y p e : v a l u e . k i n d ,
/ / h a n d l e : v a l u e ,
/ / l e a f : i s F i l e ,
/ / e n a b l e E d i t
/ / }
/ / i f ( i s F i l e ) {
/ / f i l e L i s t . p u s h ( d a t a )
/ / } e l s e {
/ / d i r L i s t . p u s h ( d a t a )
/ / }
/ / }
/ / r e s o l v e ( [ . . . d i r L i s t , . . . f i l e L i s t ] )
/ / } c a t c h ( e r r o r ) {
/ / c o n s o l e . l o g ( e r r o r )
/ / t h i s . f i l e T r e e V i s i b l e = f a l s e
/ / r e s o l v e ( [ ] )
/ / i f ( e r r o r . t o S t r i n g ( ) . i n c l u d e s ( ' a b o r t e d ' ) ) {
/ / r e t u r n
/ / }
/ / t h i s . $ m e s s a g e . w a r n i n g ( t h i s . $ t ( ' t o o l b a r . n o t S u p p o r t T i p ' ) )
/ / }
/ / } ,
/ / 扫 描 本 地 文 件 夹
openDirectory ( ) {
this . fileTreeVisible = fals e
this . fileTreeExpand = tru e
this . rootDirName = ' '
this . $nextTick ( ( ) => {
this . fileTreeVisible = tru e
} )
} ,
/ / o p e n D i r e c t o r y ( ) {
/ / t h i s . f i l e T r e e V i s i b l e = f a l s e
/ / t h i s . f i l e T r e e E x p a n d = t r u e
/ / t h i s . r o o t D i r N a m e = ' '
/ / t h i s . $ n e x t T i c k ( ( ) = > {
/ / t h i s . f i l e T r e e V i s i b l e = t r u e
/ / } )
/ / } ,
/ / 编 辑 指 定 文 件
editLocalFile ( data ) {
if ( data . handle ) {
fileHandle = data . handl e
this . readFile ( )
}
} ,
/ / e d i t L o c a l F i l e ( d a t a ) {
/ / i f ( d a t a . h a n d l e ) {
/ / f i l e H a n d l e = d a t a . h a n d l e
/ / t h i s . r e a d F i l e ( )
/ / }
/ / } ,
/ / 导 入 指 定 文 件
async importLocalFile ( data ) {
try {
const file = await data . handle . getFile ( )
this . $refs . ImportRef . onChange ( {
raw : file ,
name : file . nam e
} )
this . $refs . ImportRef . confirm ( )
} catch ( error ) {
console . log ( error )
}
} ,
/ / a s y n c i m p o r t L o c a l F i l e ( d a t a ) {
/ / t r y {
/ / c o n s t f i l e = a w a i t d a t a . h a n d l e . g e t F i l e ( )
/ / t h i s . $ r e f s . I m p o r t R e f . o n C h a n g e ( {
/ / r a w : f i l e ,
/ / n a m e : f i l e . n a m e
/ / } )
/ / t h i s . $ r e f s . I m p o r t R e f . c o n f i r m ( )
/ / } c a t c h ( e r r o r ) {
/ / c o n s o l e . l o g ( e r r o r )
/ / }
/ / } ,
/ / 打 开 本 地 文 件
async openLocalFile ( ) {
try {
let [ _fileHandle ] = await window . showOpenFilePicker ( {
types : [
{
description : '' ,
accept : {
'application/json' : [ '.smm' ]
}
}
] ,
excludeAcceptAllOption : true ,
multiple : fals e
} )
if ( ! _fileHandle ) {
retur n
}
fileHandle = _fileHandl e
if ( fileHandle . kind === 'directory' ) {
this . $message . warning ( this . $t ( 'toolbar.selectFileTip' ) )
retur n
}
this . readFile ( )
} catch ( error ) {
console . log ( error )
if ( error . toString ( ) . includes ( 'aborted' ) ) {
retur n
}
this . $message . warning ( this . $t ( 'toolbar.notSupportTip' ) )
}
} ,
/ / 读 取 本 地 文 件
async readFile ( ) {
let file = await fileHandle . getFile ( )
let fileReader = new FileReader ( )
fileReader . onload = async ( ) => {
this . $store . commit ( 'setIsHandleLocalFile' , true )
this . setData ( fileReader . result )
Notification . closeAll ( )
Notification ( {
title : this . $t ( 'toolbar.tip' ) ,
message : ` ${ this . $t ( 'toolbar.editingLocalFileTipFront' ) } ${ file . nam e
} $ { this . $t ( 'toolbar.editingLocalFileTipEnd' ) } ` ,
duration : 0 ,
showClose : tru e
} )
}
fileReader . readAsText ( file )
} ,
/ / a s y n c o p e n L o c a l F i l e ( ) {
/ / t r y {
/ / l e t [ _ f i l e H a n d l e ] = a w a i t w i n d o w . s h o w O p e n F i l e P i c k e r ( {
/ / t y p e s : [
/ / {
/ / d e s c r i p t i o n : ' ' ,
/ / a c c e p t : {
/ / ' a p p l i c a t i o n / j s o n ' : [ ' . s m m ' ]
/ / }
/ / }
/ / ] ,
/ / e x c l u d e A c c e p t A l l O p t i o n : t r u e ,
/ / m u l t i p l e : f a l s e
/ / } )
/ / i f ( ! _ f i l e H a n d l e ) {
/ / r e t u r n
/ / }
/ / f i l e H a n d l e = _ f i l e H a n d l e
/ / i f ( f i l e H a n d l e . k i n d = = = ' d i r e c t o r y ' ) {
/ / t h i s . $ m e s s a g e . w a r n i n g ( t h i s . $ t ( ' t o o l b a r . s e l e c t F i l e T i p ' ) )
/ / r e t u r n
/ / }
/ / t h i s . r e a d F i l e ( )
/ / } c a t c h ( e r r o r ) {
/ / c o n s o l e . l o g ( e r r o r )
/ / i f ( e r r o r . t o S t r i n g ( ) . i n c l u d e s ( ' a b o r t e d ' ) ) {
/ / r e t u r n
/ / }
/ / t h i s . $ m e s s a g e . w a r n i n g ( t h i s . $ t ( ' t o o l b a r . n o t S u p p o r t T i p ' ) )
/ / }
/ / } ,
/ / / / 读 取 本 地 文 件
/ / a s y n c r e a d F i l e ( ) {
/ / l e t f i l e = a w a i t f i l e H a n d l e . g e t F i l e ( )
/ / l e t f i l e R e a d e r = n e w F i l e R e a d e r ( )
/ / f i l e R e a d e r . o n l o a d = a s y n c ( ) = > {
/ / t h i s . $ s t o r e . c o m m i t ( ' s e t I s H a n d l e L o c a l F i l e ' , t r u e )
/ / t h i s . s e t D a t a ( f i l e R e a d e r . r e s u l t )
/ / N o t i f i c a t i o n . c l o s e A l l ( )
/ / N o t i f i c a t i o n ( {
/ / t i t l e : t h i s . $ t ( ' t o o l b a r . t i p ' ) ,
/ / m e s s a g e : ` $ { t h i s . $ t ( ' t o o l b a r . e d i t i n g L o c a l F i l e T i p F r o n t ' ) } $ { f i l e . n a m e
/ / } $ { t h i s . $ t ( ' t o o l b a r . e d i t i n g L o c a l F i l e T i p E n d ' ) } ` ,
/ / d u r a t i o n : 0 ,
/ / s h o w C l o s e : t r u e
/ / } )
/ / }
/ / f i l e R e a d e r . r e a d A s T e x t ( f i l e )
/ / } ,
/ / 渲 染 读 取 的 数 据
setData ( str ) {
try {
let data = JSON . parse ( str )
if ( typeof data !== 'object' ) {
throw new Error ( this . $t ( 'toolbar.fileContentError' ) )
}
if ( data . root ) {
this . isFullDataFile = tru e
} else {
this . isFullDataFile = fals e
data = {
... exampleData ,
root : dat a
}
}
this . $bus . $emit ( 'setData' , data )
} catch ( error ) {
console . log ( error )
this . $message . error ( this . $t ( 'toolbar.fileOpenFailed' ) )
}
} ,
/ / s e t D a t a ( s t r ) {
/ / t r y {
/ / l e t d a t a = J S O N . p a r s e ( s t r )
/ / i f ( t y p e o f d a t a ! = = ' o b j e c t ' ) {
/ / t h r o w n e w E r r o r ( t h i s . $ t ( ' t o o l b a r . f i l e C o n t e n t E r r o r ' ) )
/ / }
/ / i f ( d a t a . r o o t ) {
/ / t h i s . i s F u l l D a t a F i l e = t r u e
/ / } e l s e {
/ / t h i s . i s F u l l D a t a F i l e = f a l s e
/ / d a t a = {
/ / . . . e x a m p l e D a t a ,
/ / r o o t : d a t a
/ / }
/ / }
/ / t h i s . $ b u s . $ e m i t ( ' s e t D a t a ' , d a t a )
/ / } c a t c h ( e r r o r ) {
/ / c o n s o l e . l o g ( e r r o r )
/ / t h i s . $ m e s s a g e . e r r o r ( t h i s . $ t ( ' t o o l b a r . f i l e O p e n F a i l e d ' ) )
/ / }
/ / } ,
/ / 写 入 本 地 文 件
async writeLocalFile ( content ) {
if ( ! fileHandle || ! this . isHandleLocalFile ) {
this . waitingWriteToLocalFile = fals e
retur n
}
if ( ! this . isFullDataFile ) {
content = content . roo t
}
let string = JSON . stringify ( content )
const writable = await fileHandle . createWritable ( )
await writable . write ( string )
await writable . close ( )
this . waitingWriteToLocalFile = fals e
} ,
/ / a s y n c w r i t e L o c a l F i l e ( c o n t e n t ) {
/ / i f ( ! f i l e H a n d l e | | ! t h i s . i s H a n d l e L o c a l F i l e ) {
/ / t h i s . w a i t i n g W r i t e T o L o c a l F i l e = f a l s e
/ / r e t u r n
/ / }
/ / i f ( ! t h i s . i s F u l l D a t a F i l e ) {
/ / c o n t e n t = c o n t e n t . r o o t
/ / }
/ / l e t s t r i n g = J S O N . s t r i n g i f y ( c o n t e n t )
/ / c o n s t w r i t a b l e = a w a i t f i l e H a n d l e . c r e a t e W r i t a b l e ( )
/ / a w a i t w r i t a b l e . w r i t e ( s t r i n g )
/ / a w a i t w r i t a b l e . c l o s e ( )
/ / t h i s . w a i t i n g W r i t e T o L o c a l F i l e = f a l s e
/ / } ,
/ / 创 建 本 地 文 件
async createNewLocalFile ( ) {
await this . createLocalFile ( exampleData )
} ,
eventHandler ( e ) {
const eventData = e . data
let mindData = getData ( )
if ( eventData . type === 'init' ) {
/ / m a r k d o w n T i t l e = e v e n t D a t a . t i t l e ? e v e n t D a t a . t i t l e : ' 未 命 名 文 稿 '
const data = eventData . data
/ / c o n s o l e . l o g ( d a t a )
if ( ! data ) {
/ / s e t T a k e O v e r A p p M e t h o d s ( i n i t D a t a )
return ;
}
if ( isBase64 ( data . content ) ) {
data . content = decodeBase64 ( data . content )
}
if ( isJson ( data . content ) ) {
mindData . mindMapData = JSON . parse ( data . content )
} else {
mindData . mindMapData = markdown . transformMarkdownTo ( data . content )
}
/ / i n i t D a t a . m i n d M a p D a t a = J S O N . p a r s e ( d a t a . c o n t e n t )
console . log ( mindData . mindMapData )
}
} ,
/ / a s y n c c r e a t e N e w L o c a l F i l e ( ) {
/ / a w a i t t h i s . c r e a t e L o c a l F i l e ( e x a m p l e D a t a )
/ / } ,
/ / 另 存 为
async saveLocalFile ( ) {
let data = getData ( )
@ -577,40 +554,40 @@ export default {
}
} ,
/ / 创 建 本 地 文 件
async createLocalFile ( content ) {
try {
let _fileHandle = await window . showSaveFilePicker ( {
types : [
{
description : '' ,
accept : { 'application/json' : [ '.smm' ] }
}
] ,
suggestedName : this . $t ( 'toolbar.defaultFileName' )
} )
if ( ! _fileHandle ) {
retur n
}
const loading = this . $loading ( {
lock : true ,
text : this . $t ( 'toolbar.creatingTip' ) ,
spinner : 'el-icon-loading' ,
background : 'rgba(0, 0, 0, 0.7) '
} )
fileHandle = _fileHandl e
this . $store . commit ( 'setIsHandleLocalFile' , true )
this . isFullDataFile = tru e
await this . writeLocalFile ( content )
await this . readFile ( )
loading . close ( )
} catch ( error ) {
console . log ( error )
if ( error . toString ( ) . includes ( 'aborted' ) ) {
retur n
}
this . $message . warning ( this . $t ( 'toolbar.notSupportTip' ) )
}
}
/ / a s y n c c r e a t e L o c a l F i l e ( c o n t e n t ) {
/ / t r y {
/ / l e t _ f i l e H a n d l e = a w a i t w i n d o w . s h o w S a v e F i l e P i c k e r ( {
/ / t y p e s : [
/ / {
/ / d e s c r i p t i o n : ' ' ,
/ / a c c e p t : { ' a p p l i c a t i o n / j s o n ' : [ ' . s m m ' ] }
/ / }
/ / ] ,
/ / s u g g e s t e d N a m e : t h i s . $ t ( ' t o o l b a r . d e f a u l t F i l e N a m e ' )
/ / } )
/ / i f ( ! _ f i l e H a n d l e ) {
/ / r e t u r n
/ / }
/ / c o n s t l o a d i n g = t h i s . $ l o a d i n g ( {
/ / l o c k : t r u e ,
/ / t e x t : t h i s . $ t ( ' t o o l b a r . c r e a t i n g T i p ' ) ,
/ / s p i n n e r : ' e l - i c o n - l o a d i n g ' ,
/ / b a c k g r o u n d : ' r g b a ( 0 , 0 , 0 , 0 . 7 ) '
/ / } )
/ / f i l e H a n d l e = _ f i l e H a n d l e
/ / t h i s . $ s t o r e . c o m m i t ( ' s e t I s H a n d l e L o c a l F i l e ' , t r u e )
/ / t h i s . i s F u l l D a t a F i l e = t r u e
/ / a w a i t t h i s . w r i t e L o c a l F i l e ( c o n t e n t )
/ / a w a i t t h i s . r e a d F i l e ( )
/ / l o a d i n g . c l o s e ( )
/ / } c a t c h ( e r r o r ) {
/ / c o n s o l e . l o g ( e r r o r )
/ / i f ( e r r o r . t o S t r i n g ( ) . i n c l u d e s ( ' a b o r t e d ' ) ) {
/ / r e t u r n
/ / }
/ / t h i s . $ m e s s a g e . w a r n i n g ( t h i s . $ t ( ' t o o l b a r . n o t S u p p o r t T i p ' ) )
/ / }
/ / }
}
}
< / script >