@@ -5,7 +5,7 @@ import * as vscode from "vscode";
55import { leetCodeExecutor } from "../leetCodeExecutor" ;
66import { leetCodeManager } from "../leetCodeManager" ;
77import { IQuickItemEx } from "../shared" ;
8- import { DialogType , promptForOpenOutputChannel , promptForSignIn } from "../utils/uiUtils" ;
8+ import { DialogOptions , DialogType , promptForOpenOutputChannel , promptForSignIn } from "../utils/uiUtils" ;
99
1010export async function getSessionList ( ) :Promise < ISession [ ] > {
1111const signInStatus :string | undefined = leetCodeManager . getUser ( ) ;
@@ -32,48 +32,64 @@ export async function getSessionList(): Promise<ISession[]> {
3232return sessions ;
3333}
3434
35- export async function selectSession ( ) :Promise < void > {
36- const choice :IQuickItemEx < string > | undefined = await vscode . window . showQuickPick ( parseSessionsToPicks ( ) ) ;
35+ export async function manageSessions ( ) :Promise < void > {
36+ const choice :IQuickItemEx < ISession | string > | undefined = await vscode . window . showQuickPick ( parseSessionsToPicks ( true /* includeOperation */ ) ) ;
3737if ( ! choice || choice . description === "Active" ) {
3838return ;
3939}
40- if ( choice . value === ":createNewSession" ) {
41- await vscode . commands . executeCommand ( "leetcode.createSession" ) ;
40+ if ( choice . value === ":createSession" ) {
41+ await createSession ( ) ;
42+ return ;
43+ }
44+ if ( choice . value === ":deleteSession" ) {
45+ await deleteSession ( ) ;
4246return ;
4347}
4448try {
45- await leetCodeExecutor . enableSession ( choice . value ) ;
49+ await leetCodeExecutor . enableSession ( ( choice . value as ISession ) . id ) ;
4650vscode . window . showInformationMessage ( `Successfully switched to session '${ choice . label } '.` ) ;
4751await vscode . commands . executeCommand ( "leetcode.refreshExplorer" ) ;
4852} catch ( error ) {
4953await promptForOpenOutputChannel ( "Failed to switch session. Please open the output channel for details." , DialogType . error ) ;
5054}
5155}
5256
53- async function parseSessionsToPicks ( ) :Promise < Array < IQuickItemEx < string > > > {
54- return new Promise ( async ( resolve :( res :Array < IQuickItemEx < string > > ) => void ) :Promise < void > => {
57+ async function parseSessionsToPicks ( includeOperations : boolean = false ) :Promise < Array < IQuickItemEx < ISession | string > > > {
58+ return new Promise ( async ( resolve :( res :Array < IQuickItemEx < ISession | string > > ) => void ) :Promise < void > => {
5559try {
5660const sessions :ISession [ ] = await getSessionList ( ) ;
57- const picks :Array < IQuickItemEx < string > > = sessions . map ( ( s :ISession ) => Object . assign ( { } , {
61+ const picks :Array < IQuickItemEx < ISession | string > > = sessions . map ( ( s :ISession ) => Object . assign ( { } , {
5862label :`${ s . active ?"$(check) " :"" } ${ s . name } ` ,
5963description :s . active ?"Active" :"" ,
6064detail :`AC Questions:${ s . acQuestions } , AC Submits:${ s . acSubmits } ` ,
61- value :s . id ,
65+ value :s ,
6266} ) ) ;
63- picks . push ( {
64- label :"$(plus) Create a new session" ,
65- description :"" ,
66- detail :"Click this item to create a new session" ,
67- value :":createNewSession" ,
68- } ) ;
67+
68+ if ( includeOperations ) {
69+ picks . push ( ...parseSessionManagementOperations ( ) ) ;
70+ }
6971resolve ( picks ) ;
7072} catch ( error ) {
7173return await promptForOpenOutputChannel ( "Failed to list sessions. Please open the output channel for details." , DialogType . error ) ;
7274}
7375} ) ;
7476}
7577
76- export async function createSession ( ) :Promise < void > {
78+ function parseSessionManagementOperations ( ) :Array < IQuickItemEx < string > > {
79+ return [ {
80+ label :"$(plus) Create a session" ,
81+ description :"" ,
82+ detail :"Click this item to create a session" ,
83+ value :":createSession" ,
84+ } , {
85+ label :"$(trashcan) Delete a session" ,
86+ description :"" ,
87+ detail :"Click this item to DELETE a session" ,
88+ value :":deleteSession" ,
89+ } ] ;
90+ }
91+
92+ async function createSession ( ) :Promise < void > {
7793const session :string | undefined = await vscode . window . showInputBox ( {
7894prompt :"Enter the new session name." ,
7995validateInput :( s :string ) :string | undefined => s && s . trim ( ) ?undefined :"Session name must not be empty" ,
@@ -89,6 +105,47 @@ export async function createSession(): Promise<void> {
89105}
90106}
91107
108+ async function deleteSession ( ) :Promise < void > {
109+ const choice :IQuickItemEx < ISession | string > | undefined = await vscode . window . showQuickPick (
110+ parseSessionsToPicks ( false /* includeOperation */ ) ,
111+ { placeHolder :"Please select the session you want to delete" } ,
112+ ) ;
113+ if ( ! choice ) {
114+ return ;
115+ }
116+
117+ const selectedSession :ISession = choice . value as ISession ;
118+ if ( selectedSession . active ) {
119+ vscode . window . showInformationMessage ( "Cannot delete an active session." ) ;
120+ return ;
121+ }
122+
123+ const action :vscode . MessageItem | undefined = await vscode . window . showWarningMessage (
124+ `This operation cannot be reverted. Are you sure to delete the session:${ selectedSession . name } ?` ,
125+ DialogOptions . yes ,
126+ DialogOptions . no ,
127+ ) ;
128+ if ( action !== DialogOptions . yes ) {
129+ return ;
130+ }
131+
132+ const confirm :string | undefined = await vscode . window . showInputBox ( {
133+ prompt :"Enter 'yes' to confirm deleting the session" ,
134+ validateInput :( value :string ) :string => {
135+ if ( value === "yes" ) {
136+ return "" ;
137+ } else {
138+ return "Enter 'yes' to confirm" ;
139+ }
140+ } ,
141+ } ) ;
142+
143+ if ( confirm === "yes" ) {
144+ await leetCodeExecutor . deleteSession ( selectedSession . id ) ;
145+ vscode . window . showInformationMessage ( "The session has been successfully deleted." ) ;
146+ }
147+ }
148+
92149export interface ISession {
93150active :boolean ;
94151id :string ;