@@ -14272,9 +14272,9 @@ define("document/DocumentCommandHandlers", function (require, exports, module) {
1427214272 }
1427314273
1427414274 function raceAgainstTime(promise, timeout = 2000) {
14275- const timeoutPromise = new Promise((resolve , reject) => {
14275+ const timeoutPromise = new Promise((_resolve , reject) => {
1427614276 setTimeout(() => {
14277- reject(new Error(" Timed out after 3 seconds" ));
14277+ reject(new Error(` Timed out after ${timeout} seconds` ));
1427814278 }, timeout);
1427914279 });
1428014280
@@ -14418,9 +14418,49 @@ define("document/DocumentCommandHandlers", function (require, exports, module) {
1441814418 };
1441914419 }
1442014420
14421+ async function _safeFlushDB() {
14422+ // close should not be interrupted.
14423+ try{
14424+ await window.PhStore.flushDB();
14425+ } catch (e) {
14426+ console.error(e);
14427+ }
14428+ }
14429+
14430+ async function _safeNodeTerminate() {
14431+ // close should not be interrupted.
14432+ try{
14433+ await NodeConnector.terminateNode();
14434+ } catch (e) {
14435+ console.error(e);
14436+ }
14437+ }
14438+
1442114439 let closeInProgress;
14440+ let closeClickCounter = 0;
14441+ const CLOSE_TIMER_RESET_INTERVAL = 3000;
14442+ let closeTimer = setTimeout(()=>{
14443+ closeClickCounter = 0;
14444+ closeTimer = null;
14445+ }, CLOSE_TIMER_RESET_INTERVAL);
14446+
14447+ function _forceQuitIfNeeded() {
14448+ closeClickCounter++;
14449+ if(closeTimer){
14450+ clearTimeout(closeTimer);
14451+ }
14452+ closeTimer = setInterval(()=>{
14453+ closeClickCounter = 0;
14454+ closeTimer = null;
14455+ }, CLOSE_TIMER_RESET_INTERVAL);
14456+ if(closeClickCounter >= 3) {
14457+ // the user clicked the close button 3 times in the last 4 secs, he's desperate, close the window now!.
14458+ Phoenix.app.closeWindow();
14459+ }
14460+ }
1442214461 function attachTauriUnloadHandler() {
1442314462 window.__TAURI__.window.appWindow.onCloseRequested((event)=>{
14463+ _forceQuitIfNeeded();
1442414464 if(closeInProgress){
1442514465 event.preventDefault();
1442614466 return;
@@ -14430,10 +14470,11 @@ define("document/DocumentCommandHandlers", function (require, exports, module) {
1443014470 event.preventDefault();
1443114471 _handleWindowGoingAway(null, closeSuccess=>{
1443214472 console.log('close success: ', closeSuccess);
14433- raceAgainstTime(window.PhStore.flushDB ())
14473+ raceAgainstTime(_safeFlushDB ())
1443414474 .finally(()=>{
14435- raceAgainstTime(NodeConnector.terminateNode ())
14475+ raceAgainstTime(_safeNodeTerminate ())
1443614476 .finally(()=>{
14477+ closeInProgress = false;
1443714478 Phoenix.app.closeWindow();
1443814479 });
1443914480 });
@@ -33204,6 +33245,9 @@ table tr{background-color:#fff;border-top:1px solid #c6cbd1}table tr:nth-child(2
3320433245 return getNoPreviewURL(Strings.DESCRIPTION_LIVEDEV_PREVIEW_RESTRICTED,
3320533246 Strings.DESCRIPTION_LIVEDEV_PREVIEW_RESTRICTED_DETAILS);
3320633247 }
33248+ if(!utils.isPreviewableFile(fullPath)){
33249+ return getNoPreviewURL();
33250+ }
3320733251 return `${staticServerURL}externalProject/${path.basename(fullPath)}`;
3320833252 }
3320933253
@@ -34665,6 +34709,8 @@ define("extensionsIntegrated/icons/main", function (require, exports, module) {
3466534709 latex: "ffont-tex",
3466634710 tex: "ffont-tex",
3466734711
34712+ pdf: "ffont-pdf",
34713+
3466834714 psd: 'devicon-photoshop-plain',
3466934715 ai: 'devicon-illustrator-plain',
3467034716 image: 'fa-image fa-solid',
@@ -77120,8 +77166,8 @@ define("nls/root/strings", {
7712077166 "PREVIEW": "Preview",
7712177167 "BUILD_WEBSITE": "Build Website",
7712277168 "VIEW_MORE": "View More...",
77123- "NEW_PROJECT_NOTIFICATION": "Click this icon to create a new project. </br> <img src=\"extensions/default/Phoenix /images/new_project.png\"> <br/> <a href='#' style='float:right;'>ok</a>",
77124- "BEAUTIFY_CODE_NOTIFICATION": "Click here or press <b>`{0}`</b> to Beautify code. </br> <img src=\"extensions/default/Phoenix /images/beautify.gif\"> <br/> <a href='#' style='float:right;'>ok</a>",
77169+ "NEW_PROJECT_NOTIFICATION": "Click this icon to create a new project. </br> <img src=\"styles /images/new_project.png\"> <br/> <a href='#' style='float:right;'>ok</a>",
77170+ "BEAUTIFY_CODE_NOTIFICATION": "Click here or press <b>`{0}`</b> to Beautify code. </br> <img src=\"styles /images/beautify.gif\"> <br/> <a href='#' style='float:right;'>ok</a>",
7712577171 "DEFAULT_PROJECT_NOTIFICATION": "Click here to open the <br/><b>default project</b> in phoenix. </br> <a href='#' style='float:right;'>ok</a>",
7712677172 "DIRECTORY_REPLACE_MESSAGE": "The selected folder <span class='dialog-filename'>{0}</span> is not empty. Are you sure you want to replace the folder contents with the project?",
7712777173 "BUILD_WEBSITE_SECTION": "Build Website",
@@ -115965,6 +116011,8 @@ define("project/WorkingSetSort", function (require, exports, module) {
115965116011 *
115966116012 */
115967116013
116014+ /*global path*/
116015+
115968116016/**
115969116017 * WorkingSetView generates the UI for the list of the files user is editing based on the model provided by EditorManager.
115970116018 * The UI allows the user to see what files are open/dirty and allows them to close files and specify the current editor.
@@ -115977,6 +116025,7 @@ define("project/WorkingSetView", function (require, exports, module) {
115977116025 var AppInit = require("utils/AppInit"),
115978116026 DocumentManager = require("document/DocumentManager"),
115979116027 MainViewManager = require("view/MainViewManager"),
116028+ ProjectManager = require("project/ProjectManager"),
115980116029 CommandManager = require("command/CommandManager"),
115981116030 Commands = require("command/Commands"),
115982116031 Menus = require("command/Menus"),
@@ -116833,7 +116882,7 @@ define("project/WorkingSetView", function (require, exports, module) {
116833116882 } else {
116834116883 this.$openFilesContainer.show();
116835116884 this.$workingSetListViewHeader.show();
116836- this._checkForDuplicatesInWorkingTree ();
116885+ this._checkForDuplicateAndNonProjectFiles ();
116837116886 }
116838116887 };
116839116888
@@ -116942,6 +116991,32 @@ define("project/WorkingSetView", function (require, exports, module) {
116942116991 }
116943116992 };
116944116993
116994+ /**
116995+ * Adds full directory names to elements representing passed files in working tree
116996+ * @private
116997+ * @param {Array.<string>} filesPathList - list of fullPath strings
116998+ */
116999+ WorkingSetView.prototype._addFullDirectoryNamesToWorkingTreeFiles = function (filesPathList) {
117000+ // filesList must have at least two files in it for this to make sense
117001+ if (!filesPathList.length) {
117002+ return;
117003+ }
117004+
117005+ // Go through open files and add directories to appropriate entries
117006+ this.$openFilesContainer.find("ul > li").each(function () {
117007+ const $li = $(this);
117008+ let filePath = $li.data(_FILE_KEY).fullPath;
117009+ const io = filesPathList.indexOf(filePath);
117010+ if (io !== -1) {
117011+ let dirPath = path.dirname(filePath);
117012+ dirPath = Phoenix.app.getDisplayPath(dirPath);
117013+ const $dir = $(`<span title='${Phoenix.app.getDisplayPath(filePath)}' class='directory'/>`)
117014+ .html(" — " + dirPath);
117015+ $li.children("a").append($dir);
117016+ }
117017+ });
117018+ };
117019+
116945117020 /**
116946117021 * Adds directory names to elements representing passed files in working tree
116947117022 * @private
@@ -116976,9 +117051,10 @@ define("project/WorkingSetView", function (require, exports, module) {
116976117051 * and adds a parent directory name to them
116977117052 * @private
116978117053 */
116979- WorkingSetView.prototype._checkForDuplicatesInWorkingTree = function () {
116980- var self = this,
117054+ WorkingSetView.prototype._checkForDuplicateAndNonProjectFiles = function () {
117055+ let self = this,
116981117056 map = {},
117057+ externalProjectFiles = [],
116982117058 fileList = MainViewManager.getWorkingSet(MainViewManager.ALL_PANES);
116983117059
116984117060 // We need to always clear current directories as files could be removed from working tree.
@@ -116987,14 +117063,20 @@ define("project/WorkingSetView", function (require, exports, module) {
116987117063 // Go through files and fill map with arrays of files.
116988117064 fileList.forEach(function (file) {
116989117065 // Use the same function that is used to create html for file.
116990- var displayHtml = ViewUtils.getFileEntryDisplay (file);
117066+ const displayName = path.basename (file.fullPath );
116991117067
116992- if (!map[displayHtml]) {
116993- map[displayHtml] = [];
117068+ if (!map[displayName]) {
117069+ map[displayName] = [];
117070+ }
117071+ if(ProjectManager.isWithinProject(file)){
117072+ map[displayName].push(file);
117073+ } else {
117074+ externalProjectFiles.push(file.fullPath);
116994117075 }
116995- map[displayHtml].push(file);
116996117076 });
116997117077
117078+ self._addFullDirectoryNamesToWorkingTreeFiles(externalProjectFiles);
117079+
116998117080 // Go through the map and solve the arrays with length over 1. Ignore the rest.
116999117081 _.forEach(map, function (value) {
117000117082 if (value.length > 1) {
@@ -117190,7 +117272,7 @@ define("project/WorkingSetView", function (require, exports, module) {
117190117272 if (paneId === this.paneId) {
117191117273 this._rebuildViewList(true);
117192117274 } else {
117193- this._checkForDuplicatesInWorkingTree ();
117275+ this._checkForDuplicateAndNonProjectFiles ();
117194117276 }
117195117277 };
117196117278
@@ -117205,7 +117287,7 @@ define("project/WorkingSetView", function (require, exports, module) {
117205117287 if (paneId === this.paneId) {
117206117288 this._rebuildViewList(true);
117207117289 } else {
117208- this._checkForDuplicatesInWorkingTree ();
117290+ this._checkForDuplicateAndNonProjectFiles ();
117209117291 }
117210117292 };
117211117293
@@ -117245,10 +117327,10 @@ define("project/WorkingSetView", function (require, exports, module) {
117245117327 /*
117246117328 * When this event is handled by a pane that is not being updated then
117247117329 * the suppressRedraw flag does not need to be respected.
117248- * _checkForDuplicatesInWorkingTree () does not remove any entries so it's
117330+ * _checkForDuplicateAndNonProjectFiles () does not remove any entries so it's
117249117331 * safe to call at any time.
117250117332 */
117251- this._checkForDuplicatesInWorkingTree ();
117333+ this._checkForDuplicateAndNonProjectFiles ();
117252117334 }
117253117335 };
117254117336
@@ -117271,7 +117353,7 @@ define("project/WorkingSetView", function (require, exports, module) {
117271117353
117272117354 this._redraw();
117273117355 } else {
117274- this._checkForDuplicatesInWorkingTree ();
117356+ this._checkForDuplicateAndNonProjectFiles ();
117275117357 }
117276117358 };
117277117359
@@ -117311,7 +117393,7 @@ define("project/WorkingSetView", function (require, exports, module) {
117311117393 if (this.paneId === paneId) {
117312117394 this._rebuildViewList(true);
117313117395 } else {
117314- this._checkForDuplicatesInWorkingTree ();
117396+ this._checkForDuplicateAndNonProjectFiles ();
117315117397 }
117316117398 };
117317117399
@@ -132693,7 +132775,8 @@ define("utils/ValidationUtils", function (require, exports, module) {
132693132775define("utils/ViewUtils", function (require, exports, module) {
132694132776
132695132777
132696- var _ = require("thirdparty/lodash"),
132778+ const _ = require("thirdparty/lodash"),
132779+ ProjectManager = require("project/ProjectManager"),
132697132780 LanguageManager = require("language/LanguageManager");
132698132781
132699132782 var SCROLL_SHADOW_HEIGHT = 5;
@@ -133066,12 +133149,18 @@ define("utils/ViewUtils", function (require, exports, module) {
133066133149 var name = entry.name,
133067133150 ext = LanguageManager.getCompoundFileExtension(name),
133068133151 i = name.lastIndexOf("." + ext);
133069-
133152+ let hoverPath = ProjectManager.makeProjectRelativeIfPossible(entry.fullPath);
133153+ if(Phoenix.browser.isTauri) {
133154+ hoverPath = Phoenix.app.getDisplayPath(entry.fullPath);
133155+ }
133156+ hoverPath = hoverPath || "";
133070133157 if (i > 0) {
133158+ const baseName = _.escape(name.substring(0, i)),
133159+ extension = _.escape(name.substring(i));
133071133160 // Escape all HTML-sensitive characters in filename.
133072- name = _.escape(name.substring(0, i)) + "< span class='extension'>" + _.escape(name.substring(i)) + " </span>" ;
133161+ name = `<span title='${hoverPath}' class='baseName'>${baseName}</ span><span title='${hoverPath}' class='extension'>${extension} </span>` ;
133073133162 } else {
133074- name = _.escape(name);
133163+ name = `<span title='${hoverPath}' class='baseName'>${ _.escape(name)}</span>` ;
133075133164 }
133076133165
133077133166 return name;
0 commit comments