@@ -1635,113 +1635,127 @@ export async function onOpenFile(uri?: URI, source: string = "unknown"): Promise
16351635 loadAllServicesBeforeInit ( project ) ;
16361636 const loadServiceTime = performance . now ( ) - t ;
16371637
1638- await toast
1639- . promise (
1640- async ( ) => {
1641- await project . init ( ) ;
1642- loadAllServicesAfterInit ( project ) ;
1643- } ,
1644- {
1645- loading : "正在打开文件..." ,
1646- success : async ( ) => {
1647- if ( upgraded ) {
1648- project . stage = deserialize ( upgraded . data , project ) ;
1649- project . attachments = upgraded . attachments ;
1650- // 更新引用关系,包括双向线的偏移状态
1651- project . stageManager . updateReferences ( ) ;
1638+ try {
1639+ await toast
1640+ . promise (
1641+ async ( ) => {
1642+ await project . init ( ) ;
1643+ if ( project . state !== ProjectState . Saved ) {
1644+ // 用户取消了升级对话框,不打开文件
1645+ throw new Error ( "USER_CANCELLED" ) ;
16521646 }
1653- const readFileTime = performance . now ( ) - t ;
1654- store . set ( projectsAtom , [ ...store . get ( projectsAtom ) , project ] ) ;
1655- store . set ( activeProjectAtom , project ) ;
1656- setTimeout ( ( ) => {
1657- project . camera . reset ( ) ;
1658- } , 100 ) ;
1659- await RecentFileManager . addRecentFileByUri ( uri ) ;
1660- Telemetry . event ( "打开文件" , {
1661- loadServiceTime,
1662- readFileTime,
1663- source,
1664- } ) ;
1647+ loadAllServicesAfterInit ( project ) ;
1648+ } ,
1649+ {
1650+ loading : "正在打开文件..." ,
1651+ success : async ( ) => {
1652+ if ( upgraded ) {
1653+ project . stage = deserialize ( upgraded . data , project ) ;
1654+ project . attachments = upgraded . attachments ;
1655+ // 更新引用关系,包括双向线的偏移状态
1656+ project . stageManager . updateReferences ( ) ;
1657+ }
1658+ const readFileTime = performance . now ( ) - t ;
1659+ store . set ( projectsAtom , [ ...store . get ( projectsAtom ) , project ] ) ;
1660+ store . set ( activeProjectAtom , project ) ;
1661+ setTimeout ( ( ) => {
1662+ project . camera . reset ( ) ;
1663+ } , 100 ) ;
1664+ await RecentFileManager . addRecentFileByUri ( uri ) ;
1665+ Telemetry . event ( "打开文件" , {
1666+ loadServiceTime,
1667+ readFileTime,
1668+ source,
1669+ } ) ;
16651670
1666- // 处理同名TXT文件内容(仅在用户直接打开文件且设置项开启时执行,生成双链时跳过)
1667- if (
1668- Settings . autoImportTxtFileWhenOpenPrg &&
1669- source !== "ReferenceBlockNode跳转打开-prg文件" &&
1670- source !== "ReferencesWindow跳转打开-prg文件"
1671- ) {
1672- setTimeout ( async ( ) => {
1673- try {
1674- // 构建TXT文件路径
1675- const prgPath = uri . fsPath ;
1676- const txtPath = prgPath . replace ( / \. p r g $ / , ".txt" ) ;
1671+ // 处理同名TXT文件内容(仅在用户直接打开文件且设置项开启时执行,生成双链时跳过)
1672+ if (
1673+ Settings . autoImportTxtFileWhenOpenPrg &&
1674+ source !== "ReferenceBlockNode跳转打开-prg文件" &&
1675+ source !== "ReferencesWindow跳转打开-prg文件"
1676+ ) {
1677+ setTimeout ( async ( ) => {
1678+ try {
1679+ // 构建TXT文件路径
1680+ const prgPath = uri . fsPath ;
1681+ const txtPath = prgPath . replace ( / \. p r g $ / , ".txt" ) ;
16771682
1678- // 检查TXT文件是否存在
1679- if ( await exists ( txtPath ) ) {
1680- // 读取TXT文件内容
1681- const txtContent = await readFile ( txtPath ) ;
1682- const lines = new TextDecoder ( )
1683- . decode ( txtContent )
1684- . split ( "\n" )
1685- . filter ( ( line ) => line . trim ( ) !== "" ) ;
1683+ // 检查TXT文件是否存在
1684+ if ( await exists ( txtPath ) ) {
1685+ // 读取TXT文件内容
1686+ const txtContent = await readFile ( txtPath ) ;
1687+ const lines = new TextDecoder ( )
1688+ . decode ( txtContent )
1689+ . split ( "\n" )
1690+ . filter ( ( line ) => line . trim ( ) !== "" ) ;
16861691
1687- if ( lines . length > 0 ) {
1688- // 获取舞台上所有实体
1689- const entities = project . stageManager . getEntities ( ) ;
1692+ if ( lines . length > 0 ) {
1693+ // 获取舞台上所有实体
1694+ const entities = project . stageManager . getEntities ( ) ;
16901695
1691- // 计算外接矩形
1692- let startY = 0 ;
1693- if ( entities . length > 0 ) {
1694- const boundingRect = Rectangle . getBoundingRectangle (
1695- entities . map ( ( entity ) => entity . collisionBox . getRectangle ( ) ) ,
1696- ) ;
1697- startY = boundingRect . bottom ;
1698- }
1696+ // 计算外接矩形
1697+ let startY = 0 ;
1698+ if ( entities . length > 0 ) {
1699+ const boundingRect = Rectangle . getBoundingRectangle (
1700+ entities . map ( ( entity ) => entity . collisionBox . getRectangle ( ) ) ,
1701+ ) ;
1702+ startY = boundingRect . bottom ;
1703+ }
16991704
1700- // 创建并添加文本节点
1701- for ( let i = 0 ; i < lines . length ; i ++ ) {
1702- const line = lines [ i ] ;
1703- const textNode = new TextNode ( project , {
1704- text : line ,
1705- collisionBox : new CollisionBox ( [
1706- new Rectangle ( new Vector ( 0 , startY + i * 100 ) , new Vector ( 300 , 100 ) ) ,
1707- ] ) ,
1708- sizeAdjust : "auto" ,
1709- } ) ;
1710- project . stageManager . add ( textNode ) ;
1711- }
1705+ // 创建并添加文本节点
1706+ for ( let i = 0 ; i < lines . length ; i ++ ) {
1707+ const line = lines [ i ] ;
1708+ const textNode = new TextNode ( project , {
1709+ text : line ,
1710+ collisionBox : new CollisionBox ( [
1711+ new Rectangle ( new Vector ( 0 , startY + i * 100 ) , new Vector ( 300 , 100 ) ) ,
1712+ ] ) ,
1713+ sizeAdjust : "auto" ,
1714+ } ) ;
1715+ project . stageManager . add ( textNode ) ;
1716+ }
17121717
1713- // 清空TXT文件内容,避免下次打开时重复吸入
1714- await writeFile ( txtPath , new TextEncoder ( ) . encode ( "" ) ) ;
1718+ // 清空TXT文件内容,避免下次打开时重复吸入
1719+ await writeFile ( txtPath , new TextEncoder ( ) . encode ( "" ) ) ;
17151720
1716- // 显示Toast提示
1717- toast . success ( `已从同名TXT文件导入 ${ lines . length } 条内容到舞台左下角` ) ;
1721+ // 显示Toast提示
1722+ toast . success ( `已从同名TXT文件导入 ${ lines . length } 条内容到舞台左下角` ) ;
17181723
1719- // 发送遥测
1720- Telemetry . event ( "txt_content_imported" , {
1721- line_count : lines . length ,
1722- } ) ;
1724+ // 发送遥测
1725+ Telemetry . event ( "txt_content_imported" , {
1726+ line_count : lines . length ,
1727+ } ) ;
17231728
1724- // 设置项目状态为未保存
1725- project . state = ProjectState . Unsaved ;
1729+ // 设置项目状态为未保存
1730+ project . state = ProjectState . Unsaved ;
1731+ }
17261732 }
1733+ } catch ( e ) {
1734+ console . warn ( "处理TXT文件时发生错误:" , e ) ;
17271735 }
1728- } catch ( e ) {
1729- console . warn ( "处理TXT文件时发生错误:" , e ) ;
1730- }
1731- } , 200 ) ;
1732- }
1736+ } , 200 ) ;
1737+ }
17331738
1734- return `耗时 ${ readFileTime } ms,共 ${ project . stage . length } 个舞台对象,${ project . attachments . size } 个附件` ;
1735- } ,
1736- error : ( e ) => {
1737- Telemetry . event ( "打开文件失败" , {
1738- error : String ( e ) ,
1739- } ) ;
1740- return `读取时发生错误,已发送错误报告,可在群内联系开发者\n${ String ( e ) } ` ;
1739+ return `耗时 ${ readFileTime } ms,共 ${ project . stage . length } 个舞台对象,${ project . attachments . size } 个附件` ;
1740+ } ,
1741+ error : ( e ) => {
1742+ if ( e instanceof Error && e . message === "USER_CANCELLED" ) {
1743+ return "已取消打开文件" ;
1744+ }
1745+ Telemetry . event ( "打开文件失败" , {
1746+ error : String ( e ) ,
1747+ } ) ;
1748+ return `读取时发生错误,已发送错误报告,可在群内联系开发者\n${ String ( e ) } ` ;
1749+ } ,
17411750 } ,
1742- } ,
1743- )
1744- . unwrap ( ) ;
1751+ )
1752+ . unwrap ( ) ;
1753+ } catch ( e ) {
1754+ if ( e instanceof Error && e . message === "USER_CANCELLED" ) {
1755+ return undefined ; // 用户取消,静默处理
1756+ }
1757+ throw e ;
1758+ }
17451759 return project ;
17461760}
17471761
0 commit comments