Skip to content

Commit dd7b6c1

Browse files
committed
feat: in working set toggle the pin and close button, dirty icon on the right side
1 parent 4e64dd1 commit dd7b6c1

2 files changed

Lines changed: 66 additions & 40 deletions

File tree

src/project/WorkingSetView.js

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ define(function (require, exports, module) {
288288
lastPageY = startPageY,
289289
lastHit = { where: NOMANSLAND },
290290
tryClosing = $(e.target).hasClass("can-close"),
291+
tryPinning = $(e.target).closest(".file-status-icon").hasClass("pinned"),
291292
currentFile = MainViewManager.getCurrentlyViewedFile(),
292293
activePaneId = MainViewManager.getActivePaneId(),
293294
activeView = _views[activePaneId],
@@ -778,6 +779,14 @@ define(function (require, exports, module) {
778779
.always(function () {
779780
postDropCleanup();
780781
});
782+
} else if (tryPinning) {
783+
// Click on pin icon - toggle pin state
784+
CommandManager
785+
.execute(Commands.FILE_PIN, {file: sourceFile,
786+
paneId: sourceView.paneId})
787+
.always(function () {
788+
postDropCleanup();
789+
});
781790
} else {
782791
// Normal right and left click - select the item
783792
FileViewController.setFileViewFocus(FileViewController.WORKING_SET_VIEW);
@@ -1186,32 +1195,42 @@ define(function (require, exports, module) {
11861195
};
11871196

11881197
/**
1189-
* Updates the appearance of the list element based on the parameters provided
1198+
* Updates the appearance of the list element based on the parameters provided.
1199+
* For pinned files: shows pin icon (always visible, clickable to unpin)
1200+
* For unpinned files: shows close button on hover
1201+
* Dirty indicator is shown on the right side when file has unsaved changes
11901202
* @private
11911203
* @param {!HTMLLIElement} listElement
11921204
* @param {bool} isDirty
11931205
* @param {bool} canClose
1206+
* @param {bool} isPinned
11941207
*/
1195-
WorkingSetView.prototype._updateFileStatusIcon = function (listElement, isDirty, canClose) {
1196-
var $fileStatusIcon = listElement.find(".file-status-icon"),
1197-
showIcon = isDirty || canClose;
1208+
WorkingSetView.prototype._updateFileStatusIcon = function (listElement, isDirty, canClose, isPinned) {
1209+
let $fileStatusIcon = listElement.find(".file-status-icon"),
1210+
$dirtyIndicator = listElement.find(".working-set-dirty-indicator"),
1211+
showIcon = isPinned || canClose;
11981212

1199-
// remove icon if its not needed
1213+
// Handle file status icon (pin or close button) on LEFT side
12001214
if (!showIcon && $fileStatusIcon.length !== 0) {
12011215
$fileStatusIcon.remove();
12021216
$fileStatusIcon = null;
1203-
1204-
// create icon if its needed and doesn't exist
12051217
} else if (showIcon && $fileStatusIcon.length === 0) {
1206-
12071218
$fileStatusIcon = $("<div class='file-status-icon'></div>")
12081219
.prependTo(listElement);
12091220
}
12101221

1211-
// Set icon's class
1222+
// Set icon's class - pinned shows thumbtack, unpinned shows close on hover
12121223
if ($fileStatusIcon) {
1213-
ViewUtils.toggleClass($fileStatusIcon, "dirty", isDirty);
1214-
ViewUtils.toggleClass($fileStatusIcon, "can-close", canClose);
1224+
ViewUtils.toggleClass($fileStatusIcon, "can-close", canClose && !isPinned);
1225+
ViewUtils.toggleClass($fileStatusIcon, "pinned", isPinned);
1226+
}
1227+
1228+
// Handle dirty indicator on RIGHT side
1229+
if (!isDirty && $dirtyIndicator.length !== 0) {
1230+
$dirtyIndicator.remove();
1231+
} else if (isDirty && $dirtyIndicator.length === 0) {
1232+
$dirtyIndicator = $("<div class='working-set-dirty-indicator'></div>")
1233+
.appendTo(listElement);
12151234
}
12161235
};
12171236

@@ -1272,25 +1291,23 @@ define(function (require, exports, module) {
12721291
$newItem.addClass(provider(data));
12731292
});
12741293

1275-
// if the file is pinned, add the pin icon in the list item
1294+
// Check if the file is pinned and add the class
12761295
const isPinned = MainViewManager.isPathPinned(this.paneId, file.fullPath);
12771296
if (isPinned) {
12781297
$newItem.addClass("pinned");
1279-
const $pinIcon = $("<div class='working-set-pin-icon'><i class='fa-solid fa-thumbtack'></i></div>");
1280-
$newItem.append($pinIcon);
12811298
}
12821299

1283-
// Update the listItem's apperance
1284-
this._updateFileStatusIcon($newItem, _isOpenAndDirty(file), false);
1300+
// Update the listItem's appearance - pin icon or close button handled by _updateFileStatusIcon
1301+
this._updateFileStatusIcon($newItem, _isOpenAndDirty(file), false, isPinned);
12851302
_updateListItemSelection($newItem, selectedFile);
12861303
_makeDraggable($newItem);
12871304

12881305
$newItem.hover(
12891306
function () {
1290-
self._updateFileStatusIcon($(this), _isOpenAndDirty(file), true);
1307+
self._updateFileStatusIcon($(this), _isOpenAndDirty(file), true, isPinned);
12911308
},
12921309
function () {
1293-
self._updateFileStatusIcon($(this), _isOpenAndDirty(file), false);
1310+
self._updateFileStatusIcon($(this), _isOpenAndDirty(file), false, isPinned);
12941311
}
12951312
);
12961313
};
@@ -1405,7 +1422,9 @@ define(function (require, exports, module) {
14051422
if ($nextListItem && $nextListItem.length > 0) {
14061423
var canClose = ($listItem.find(".can-close").length === 1);
14071424
var isDirty = _isOpenAndDirty($nextListItem.data(_FILE_KEY));
1408-
this._updateFileStatusIcon($nextListItem, isDirty, canClose);
1425+
let nextFile = $nextListItem.data(_FILE_KEY);
1426+
let isPinned = MainViewManager.isPathPinned(this.paneId, nextFile.fullPath);
1427+
this._updateFileStatusIcon($nextListItem, isDirty, canClose, isPinned);
14091428
}
14101429
$listItem.remove();
14111430
}
@@ -1476,7 +1495,8 @@ define(function (require, exports, module) {
14761495
var listItem = this._findListItemFromFile(doc.file);
14771496
if (listItem) {
14781497
var canClose = $(listItem).find(".can-close").length === 1;
1479-
this._updateFileStatusIcon(listItem, doc.isDirty, canClose);
1498+
let isPinned = MainViewManager.isPathPinned(this.paneId, doc.file.fullPath);
1499+
this._updateFileStatusIcon(listItem, doc.isDirty, canClose, isPinned);
14801500
}
14811501
};
14821502

src/styles/brackets.less

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,19 +1443,6 @@ a, img {
14431443
color: @project-panel-text-2;
14441444
}
14451445

1446-
li.pinned .working-set-pin-icon {
1447-
position: absolute;
1448-
right: 10px;
1449-
top: 50%;
1450-
transform: translateY(-50%);
1451-
font-size: 9px;
1452-
color: @project-panel-text-2;
1453-
opacity: 0.7;
1454-
1455-
&:hover {
1456-
opacity: 1;
1457-
}
1458-
}
14591446
}
14601447

14611448

@@ -1619,17 +1606,12 @@ a, img {
16191606
left: 0;
16201607
top: 0;
16211608

1622-
&.dirty:before,
1623-
&.can-close:before {
1609+
&.can-close:before,
1610+
&.pinned:before {
16241611
.unicode-icon-container;
16251612
color: rgba(255, 255, 255, 0.5);
16261613
}
16271614

1628-
&.dirty:before {
1629-
content: "\2022";
1630-
line-height: 1em;
1631-
}
1632-
16331615
&.can-close:before {
16341616
content: "\00D7";
16351617
line-height: 1.1em;
@@ -1642,6 +1624,30 @@ a, img {
16421624
&.can-close:active:before {
16431625
color: rgba(255, 255, 255, 0.3);
16441626
}
1627+
1628+
&.pinned:before {
1629+
content: "\f08d";
1630+
font-family: "Font Awesome 6 Free";
1631+
font-weight: 900;
1632+
font-size: 9px;
1633+
}
1634+
1635+
&.pinned:hover:before {
1636+
color: rgba(255, 255, 255, 0.7);
1637+
}
1638+
}
1639+
1640+
.working-set-dirty-indicator {
1641+
position: absolute;
1642+
right: 10px;
1643+
top: 0;
1644+
1645+
&:before {
1646+
.unicode-icon-container;
1647+
content: "\2022";
1648+
color: rgba(255, 255, 255, 0.5);
1649+
line-height: 1em;
1650+
}
16451651
}
16461652

16471653
/* Styles for inline editors */

0 commit comments

Comments
 (0)