finish up bookmark functionality

This commit is contained in:
sawka
2023-02-21 22:10:45 -08:00
parent cc5f8f81e7
commit 7f3e688475
3 changed files with 146 additions and 22 deletions
+25 -5
View File
@@ -758,7 +758,7 @@ class LineCmd extends React.Component<{sw : ScreenWindow, line : LineType, width
</div>
</div>
<div key="spacer" className="flex-spacer"/>
<div key="pin" title="Pin" className={cn("line-icon", {"active": line.pinned})} onClick={this.clickPin}>
<div key="pin" title="Pin" className={cn("line-icon", {"active": line.pinned})} onClick={this.clickPin} style={{display: "none"}}>
<i className="fa fa-thumb-tack"/>
</div>
<div key="bookmark" title="Bookmark" className={cn("line-icon", "line-bookmark", {"active": line.bookmarked})} onClick={this.clickBookmark}>
@@ -936,6 +936,11 @@ class TextAreaInput extends React.Component<{}, {}> {
inputModel.openHistory();
return;
}
if (e.code == "ArrowUp" && e.getModifierState("Shift")) {
e.preventDefault();
inputModel.openHistory();
return;
}
if (e.code == "ArrowUp" || e.code == "ArrowDown") {
if (!inputModel.isHistoryLoaded()) {
if (e.code == "ArrowUp") {
@@ -2839,6 +2844,20 @@ class Bookmark extends React.Component<{bookmark : BookmarkType}, {}> {
model.tempCmd.set(e.target.value);
})();
}
@boundMethod
handleClick() : void {
let {bookmark} = this.props;
let model = GlobalModel.bookmarksModel;
model.selectBookmark(bookmark.bookmarkid);
}
@boundMethod
handleUse() : void {
let {bookmark} = this.props;
let model = GlobalModel.bookmarksModel;
model.useBookmark(bookmark.bookmarkid);
}
render() {
let bm = this.props.bookmark;
@@ -2859,7 +2878,7 @@ class Bookmark extends React.Component<{bookmark : BookmarkType}, {}> {
let isEditing = (model.editingBookmark.get() == bm.bookmarkid);
if (isEditing) {
return (
<div className={cn("bookmark focus-parent is-editing", {"pending-delete": model.pendingDelete.get() == bm.bookmarkid})}>
<div data-bookmarkid={bm.bookmarkid} className={cn("bookmark focus-parent is-editing", {"pending-delete": model.pendingDelete.get() == bm.bookmarkid})}>
<div className={cn("focus-indicator", {"active": isSelected})}/>
<div className="bookmark-edit">
<div className="field">
@@ -2887,7 +2906,7 @@ class Bookmark extends React.Component<{bookmark : BookmarkType}, {}> {
);
}
return (
<div className={cn("bookmark focus-parent", {"pending-delete": model.pendingDelete.get() == bm.bookmarkid})}>
<div className={cn("bookmark focus-parent", {"pending-delete": model.pendingDelete.get() == bm.bookmarkid})} onClick={this.handleClick}>
<div className={cn("focus-indicator", {"active": isSelected})}/>
<div className="bookmark-id-div">{bm.bookmarkid.substr(0, 8)}</div>
<div className="bookmark-content">
@@ -2897,6 +2916,7 @@ class Bookmark extends React.Component<{bookmark : BookmarkType}, {}> {
</div>
</If>
<div className={cn("bookmark-code", {"no-desc": !hasDesc})}>
<div className="use-button" title="Use Bookmark" onClick={this.handleUse}><i className="fa fa-check"/></div>
<code>{bm.cmdstr}</code>
</div>
</div>
@@ -2936,9 +2956,9 @@ class BookmarksView extends React.Component<{}, {}> {
<If condition={bookmarks.length > 0}>
<div className="bookmarks-help">
<div className="help-entry">
[Enter] to Select<br/>
[Arrow Up] / [Arrow Down] to Move in List<br/>
[Enter] to Use Bookmark<br/>
[Backspace/Delete]x2 or <i className="fa fa-trash"/> to Delete<br/>
[Arrow Up]/[Arrow Down]/[PageUp]/[PageDown] to Move in List<br/>
[e] or <i className="fa fa-pencil"/> to Edit<br/>
</div>
</div>
+93 -17
View File
@@ -1592,6 +1592,29 @@ class BookmarksModel {
tempDesc : OV<string> = mobx.observable.box("", {name: "bookmarkEdit-tempDesc"});
tempCmd : OV<string> = mobx.observable.box("", {name: "bookmarkEdit-tempCmd"});
showBookmarksView(bmArr : BookmarkType[]) : void {
bmArr = bmArr ?? [];
mobx.action(() => {
this.reset();
GlobalModel.activeMainView.set("bookmarks");
this.bookmarks.replace(bmArr);
if (bmArr.length > 0) {
this.activeBookmark.set(bmArr[0].bookmarkid);
}
})();
}
reset() : void {
mobx.action(() => {
this.activeBookmark.set(null);
this.editingBookmark.set(null);
this.pendingDelete.set(null);
this.tempDesc.set("");
this.tempCmd.set("");
})();
}
closeView() : void {
mobx.action(() => {
GlobalModel.activeMainView.set("session");
@@ -1603,6 +1626,33 @@ class BookmarksModel {
mobx.action(() => this.pendingDelete.set(null))();
}
useBookmark(bookmarkId : string) : void {
let bm = this.getBookmark(bookmarkId);
if (bm == null) {
return;
}
mobx.action(() => {
this.reset();
GlobalModel.activeMainView.set("session");
GlobalModel.inputModel.setCurLine(bm.cmdstr);
setTimeout(() => GlobalModel.inputModel.giveFocus(), 50);
})();
}
selectBookmark(bookmarkId : string) : void {
let bm = this.getBookmark(bookmarkId);
if (bm == null) {
return;
}
if (this.activeBookmark.get() == bookmarkId) {
return;
}
mobx.action(() => {
this.cancelEdit();
this.activeBookmark.set(bookmarkId);
})();
}
cancelEdit() : void {
mobx.action(() => {
this.pendingDelete.set(null);
@@ -1650,6 +1700,19 @@ class BookmarksModel {
return null;
}
getBookmarkPos(bookmarkId : string) : number {
if (bookmarkId == null) {
return -1;
}
for (let i=0; i<this.bookmarks.length; i++) {
let bm = this.bookmarks[i];
if (bm.bookmarkid == bookmarkId) {
return i;
}
}
return -1;
}
getActiveBookmark() : BookmarkType {
let activeBookmarkId = this.activeBookmark.get();
return this.getBookmark(activeBookmarkId);
@@ -1696,14 +1759,35 @@ class BookmarksModel {
this.handleDeleteBookmark(this.activeBookmark.get());
return;
}
if (e.code == "ArrowUp") {
}
if (e.code == "ArrowDown") {
if (e.code == "ArrowUp" || e.code == "ArrowDown" || e.code == "PageUp" || e.code == "PageDown") {
e.preventDefault();
if (this.bookmarks.length == 0) {
return;
}
let newPos = 0; // if active is null, then newPos will be 0 (select the first)
if (this.activeBookmark.get() != null) {
let amtMap = {"ArrowUp": -1, "ArrowDown": 1, "PageUp": -10, "PageDown": 10};
let amt = amtMap[e.code];
let curIdx = this.getBookmarkPos(this.activeBookmark.get());
newPos = curIdx + amt;
if (newPos < 0) {
newPos = 0;
}
if (newPos >= this.bookmarks.length) {
newPos = this.bookmarks.length-1;
}
}
let bm = this.bookmarks[newPos];
mobx.action(() => {
this.activeBookmark.set(bm.bookmarkid);
})();
return;
}
if (e.code == "Enter") {
if (this.activeBookmark.get() == null) {
return;
}
this.useBookmark(this.activeBookmark.get());
return;
}
if (e.code == "KeyE") {
@@ -1804,6 +1888,10 @@ class Model {
}
return;
}
if (e.code == "KeyB" && e.getModifierState("Meta")) {
e.preventDefault();
GlobalCommandRunner.bookmarksView();
}
}
restartLocalServer() : void {
@@ -2054,7 +2142,7 @@ class Model {
this.updateRemotes(update.remotes);
}
if ("bookmarksview" in update) {
this.showBookmarksView(update.bookmarks);
this.bookmarksModel.showBookmarksView(update.bookmarks);
}
else if ("bookmarks" in update) {
this.bookmarksModel.mergeBookmarks(update.bookmarks);
@@ -2078,18 +2166,6 @@ class Model {
// console.log("run-update>", Date.now(), interactive, update);
}
showBookmarksView(bmArr : BookmarkType[]) : void {
bmArr = bmArr ?? [];
mobx.action(() => {
this.activeMainView.set("bookmarks");
this.bookmarksModel.bookmarks.replace(bmArr);
this.bookmarksModel.activeBookmark.set(null);
if (bmArr.length > 0) {
this.bookmarksModel.activeBookmark.set(bmArr[0].bookmarkid);
}
})();
}
updateRemotes(remotes : RemoteType[]) : void {
genMergeSimpleData(this.remotes, remotes, (r) => r.remoteid, null);
}
@@ -2599,7 +2675,7 @@ class CommandRunner {
editBookmark(bookmarkId : string, desc : string, cmdstr : string) {
let kwargs = {
"nohist": "1",
"description": desc,
"desc": desc,
"cmdstr": cmdstr,
};
GlobalModel.submitCommand("bookmark", "set", [bookmarkId], kwargs, true);
+28
View File
@@ -148,6 +148,7 @@ html, body, #main {
flex-direction: row;
align-items: center;
font-size: 12px;
margin-bottom: 10px;
.help-entry {
margin-left: 20px;
@@ -237,11 +238,38 @@ html, body, #main {
}
.bookmark-code {
display: flex;
flex-direction: row;
.use-button {
flex-grow: 0;
padding: 3px;
border-radius: 3px 0 0 3px;
font-size: 12px;
height: 28px;
width: 28px;
display: flex;
align-items: center;
justify-content: center;
align-self: flex-start;
cursor: pointer;
background-color: black;
&:hover {
background-color: #777;
}
}
code {
border-left: 1px solid #777;
flex-shrink: 0;
color: white;
.mono-font();
background-color: black;
white-space: pre;
padding: 2px 8px 2px 8px;
}
padding: 4px 10px 4px 0;
margin-top: 10px;