Skip to content

Commit 0d1c86d

Browse files
committed
Unlock requests
1 parent a2b4a79 commit 0d1c86d

File tree

5 files changed

+97
-13
lines changed

5 files changed

+97
-13
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Install from vscode marketplace [SharedLock](https://marketplace.visualstudio.co
1717
![Demo](./resources/images/demo.gif)
1818

1919

20+
![UnlockRequest](./resources/images/unlockreq.gif)
21+
2022
## Screens
2123

2224
![Release](./resources/images/sharedlock_exp.png)

resources/images/unlockreq.gif

529 KB
Loading

src/conts.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const statusBarID = `${name}.statusBar`;
44
const statusBarAction = `${name}.indicatorAction`;
55
const locksViewID = `${name}.locksView`;
66
const channelID = `${name}.bus`;
7+
const channelUI = `${name}.ui`;
78

89
export enum LockCommands {
910
updateLock = `${name}.updateLock`,
@@ -27,5 +28,6 @@ export {
2728
statusBarID,
2829
statusBarAction,
2930
locksViewID,
30-
channelID
31+
channelID,
32+
channelUI
3133
};

src/storage.ts

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { commands } from "vscode";
33
import * as vs from "vscode";
44
import * as os from 'os';
55
import * as path from 'path';
6-
import { LockCommands, LockState, channelID } from "./conts";
7-
import { Tag,LockMessage } from "./types";
6+
import { LockCommands, LockState, channelID, channelUI } from "./conts";
7+
import { Tag,LockMessage, UIMessage, UIMessageType, UILockRequestMessage, UILockReplyMessage } from "./types";
88
import { logger } from "./logger";
99
import { existsSync } from "fs";
1010
import { getPathNS } from "./utils";
@@ -17,6 +17,7 @@ export class Storage {
1717
private ctx:vs.ExtensionContext;
1818
private folders:string[];
1919
private _enabled:boolean;
20+
private userChannel:string;
2021

2122
_onDidLockChanged:vs.EventEmitter<LockMessage[]>;
2223
_onDidEnabledChanged:vs.EventEmitter<boolean>;
@@ -58,26 +59,31 @@ export class Storage {
5859
console.log("Config",connectOpts,this.folders);
5960

6061
this.tag = this.getTag();
62+
this.userChannel = `${channelUI}.${this.tag.username}`;
6163
this.sub = new Redis(connectOpts);
6264
this.pub = new Redis(connectOpts);
6365
this.sub.on("connect",()=>{
6466
let txt = `[redis]: Connection made to ${host}:${port}/${db} with auth ${username || '-'}/${password ||'-'}`;
6567
console.log(txt);
6668
logger.info(txt);
67-
this.sub.subscribe(channelID,(err,count) => {
69+
this.sub.subscribe(channelID,this.userChannel,(err,count) => {
6870
if ( err ){
69-
txt = `[redis] Failed to subscribe to channed ${channelID}: ${err.message}`;
71+
txt = `[redis] Failed to subscribe to channels ${channelID}: ${err.message}`;
7072
logger.error(txt);
7173
console.error(txt,err);
7274
} else {
73-
txt = `[redis] Message bus started on ${channelID} ( count ${count})`;
75+
txt = `[redis] Message bus started on ${channelID}/${this,this.userChannel} ( count ${count})`;
7476
logger.info(txt);
7577
console.log(txt);
7678
this.startup();
7779
}
7880
});
7981
this.sub.on("message",(channel,msg)=>{
80-
this.onMessage(JSON.parse(msg));
82+
if ( channel === channelID ) {
83+
this.onMessage(JSON.parse(msg));
84+
} else {
85+
this.onUIMessage(JSON.parse(msg));
86+
}
8187
});
8288
});
8389
this.sub.on("error",(e)=>{
@@ -146,6 +152,39 @@ export class Storage {
146152
this.setContext(key,check);
147153
}
148154

155+
async onUIMessage(msg:UIMessage) {
156+
logger.info(`UI Message from ${msg.from.username}: ${msg.message}`);
157+
console.log("UI",msg);
158+
switch ( msg.type ) {
159+
case UIMessageType.lockRequest:
160+
vs.window.showWarningMessage(`👤 ${msg.from.username}${msg.message}`,{},...["Unlock!"])
161+
.then((res)=>{
162+
console.log(res);
163+
if ( res ) {
164+
this.setFileLockState(LockState.Unlocked,(msg as UILockRequestMessage).payload.file);
165+
}
166+
this.uiPub(msg.from,{
167+
type:UIMessageType.lockReply,
168+
message:res ? "Accepted" : "Rejected...",
169+
from:this.tag,
170+
payload:{
171+
file:(msg as UILockRequestMessage).payload.file,
172+
granted:Boolean(res)
173+
}
174+
});
175+
});
176+
break;
177+
case UIMessageType.lockReply:
178+
if ( (msg as UILockReplyMessage).payload.granted ) {
179+
vs.window.showWarningMessage(`${msg.message} 👤 ${msg.from.username}`);
180+
this.setFileLockState(LockState.Locked,(msg as UILockReplyMessage).payload.file);
181+
} else {
182+
vs.window.showErrorMessage(`${msg.message} 👤 ${msg.from.username}`);
183+
}
184+
break;
185+
}
186+
}
187+
149188
async onMessage(msg:LockMessage) {
150189
console.log("LOCKED MESSAGE !",msg);
151190
logger.debug('[redis]: Message',msg);
@@ -223,9 +262,6 @@ export class Storage {
223262
}
224263

225264
get(key:string) {
226-
//if (!this.enabled ) {
227-
// return;
228-
//}
229265
return this.pub.get(this.nsKey(key))
230266
.then((res:string | null)=>{
231267
if ( res ) {
@@ -260,8 +296,8 @@ export class Storage {
260296
return this.tag.host === tag.host && this.tag.username === tag.username;
261297
}
262298

263-
async setFileLockState(state:LockState) {
264-
const key = await this.getFileTag();
299+
async setFileLockState(state:LockState,aKey?:string | undefined) {
300+
const key = aKey || (await this.getFileTag());
265301
console.log("Lock state for",key,state);
266302
if ( !key ) {
267303
return;
@@ -320,11 +356,29 @@ export class Storage {
320356
if ( this.isMe(check)) {
321357
this.setFileLockState(LockState.Unlocked);
322358
} else {
323-
vs.window.showInformationMessage(`File is locked by ${check.username}`);
359+
const opts : vs.MessageOptions = {
360+
modal:false,
361+
};
362+
vs.window.showInformationMessage(`File is locked by [${check.username}]`,opts,...['Request ownership ?'])
363+
.then((item)=>{
364+
if ( item ) {
365+
this.uiPub(this.tag,{
366+
type:UIMessageType.lockRequest,
367+
from:this.tag,
368+
message:`Unlock request for ${key} ?`,
369+
payload:{
370+
file:key,
371+
}
372+
});
373+
}
374+
});
324375
}
325376
}
326377
}
327378

379+
uiPub(tag:Tag,msg:UIMessage) {
380+
this.pub.publish(`${channelUI}.${tag.username}`,JSON.stringify(msg));
381+
}
328382

329383
nsKey(key:string) {
330384
if ( !vs.window.activeTextEditor ) {

src/types.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,29 @@ export interface LockMessage {
1010
file:string;
1111
tag:Tag;
1212
}
13+
14+
export enum UIMessageType {
15+
lockRequest = "lockreq",
16+
lockReply = "lockrep"
17+
}
18+
19+
export interface UIMessagePayloadLockRequest {
20+
file:string;
21+
}
22+
23+
export interface UIMessagePayloadLockReply {
24+
granted:boolean;
25+
file:string;
26+
}
27+
28+
export interface UIMessageDef<T> {
29+
type:UIMessageType
30+
from:Tag;
31+
message:string;
32+
payload:T;
33+
}
34+
35+
export type UILockRequestMessage = UIMessageDef<UIMessagePayloadLockRequest>;
36+
export type UILockReplyMessage = UIMessageDef<UIMessagePayloadLockReply>;
37+
38+
export type UIMessage = UILockReplyMessage | UILockRequestMessage;

0 commit comments

Comments
 (0)