Skip to content

Commit 9cf6dd5

Browse files
authored
plugin state removal, cleanup, and session file fix (#493)
* plugin state removal, cleanup, and session file fix * vsix update * update menu text to reinitialize * update vsix * update command to log out * updated vsix
1 parent 22349d0 commit 9cf6dd5

12 files changed

+110
-170
lines changed

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "swdc-vscode",
33
"displayName": "Code Time",
4-
"version": "2.7.10",
4+
"version": "2.7.11",
55
"publisher": "softwaredotcom",
66
"description": "Code Time is an open source plugin that provides programming metrics right in Visual Studio Code.",
77
"author": {
@@ -95,6 +95,10 @@
9595
{
9696
"command": "codetime.exitFlowMode",
9797
"title": "Code Time: Exit Flow Mode"
98+
},
99+
{
100+
"command": "codetime.logout",
101+
"title": "Code Time: Log out"
98102
}
99103
],
100104
"configuration": [

src/DataController.ts

Lines changed: 25 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {window, commands} from 'vscode';
1+
import {commands} from 'vscode';
22
import {isResponseOk, appGet} from './http/HttpClient';
33
import {
44
getItem,
@@ -7,20 +7,16 @@ import {
77
logIt,
88
musicTimeExtInstalled,
99
editorOpsExtInstalled,
10+
showInformationMessage,
1011
} from './Util';
1112
import {initializeWebsockets} from './websockets';
1213
import {SummaryManager} from './managers/SummaryManager';
1314
import { updateFlowModeStatus } from './managers/FlowManager';
14-
import { createAnonymousUser } from './menu/AccountManager';
15-
import { ExtensionManager } from './managers/ExtensionManager';
1615

1716
let currentUser: any | null = null;
18-
let lastUserFetch: number = 0;
1917

2018
export async function getCachedSlackIntegrations() {
21-
if (!currentUser) {
22-
currentUser = await getUser();
23-
}
19+
currentUser = await getCachedUser();
2420
if (currentUser?.integration_connections?.length) {
2521
return currentUser?.integration_connections?.filter(
2622
(integration: any) => integration.status === 'ACTIVE' && (integration.integration_type_id === 14));
@@ -40,10 +36,7 @@ export function isRegistered() {
4036
}
4137

4238
export async function getUserPreferences() {
43-
if (!currentUser) {
44-
currentUser = await getUser();
45-
}
46-
39+
currentUser = await getCachedUser()
4740
if (currentUser) {
4841
let prefs = currentUser.preferences;
4942
if (prefs && typeof prefs === 'string') {
@@ -58,11 +51,6 @@ export async function getUserPreferences() {
5851
}
5952

6053
export async function getUser() {
61-
const nowMillis: number = new Date().getTime();
62-
if (currentUser && nowMillis - lastUserFetch < 2000) {
63-
return currentUser;
64-
}
65-
6654
const resp = await appGet('/api/v1/user');
6755
if (isResponseOk(resp) && resp.data) {
6856
currentUser = resp.data;
@@ -74,8 +62,6 @@ export async function getUser() {
7462
} else {
7563
setItem('authType', 'software');
7664
}
77-
78-
lastUserFetch = nowMillis;
7965
return currentUser;
8066
}
8167
return null;
@@ -106,23 +92,33 @@ export async function authenticationCompleteHandler(user: any) {
10692
}
10793

10894
// update the login status
109-
window.showInformationMessage(`Successfully logged on to Code Time`);
95+
showInformationMessage(`Successfully logged on to Code Time`);
11096

111-
updateFlowModeStatus();
97+
await reload()
98+
}
11299

113-
try {
114-
initializeWebsockets();
115-
} catch (e: any) {
116-
logIt(`Failed to initialize websockets: ${e.message}`);
117-
}
100+
return updatedUserInfo;
101+
}
102+
103+
export async function userDeletedCompletionHandler() {
104+
commands.executeCommand('codetime.logout');
105+
}
118106

119-
// re-initialize user and preferences
120-
await getUser();
107+
export async function reload() {
108+
updateFlowModeStatus();
121109

122-
// fetch after logging on
123-
SummaryManager.getInstance().updateSessionSummaryFromServer();
110+
try {
111+
initializeWebsockets();
112+
} catch (e: any) {
113+
logIt(`Failed to initialize websockets: ${e.message}`);
124114
}
125115

116+
// re-initialize user and preferences
117+
await getUser();
118+
119+
// fetch after logging on
120+
SummaryManager.getInstance().updateSessionSummaryFromServer();
121+
126122
if (musicTimeExtInstalled()) {
127123
setTimeout(() => {
128124
commands.executeCommand("musictime.refreshMusicTimeView")
@@ -135,67 +131,5 @@ export async function authenticationCompleteHandler(user: any) {
135131
}, 1000);
136132
}
137133

138-
// update the extensions if its a new user
139-
setTimeout(() => {
140-
ExtensionManager.getInstance().initialize();
141-
}, 1000);
142-
143134
commands.executeCommand('codetime.refreshCodeTimeView');
144-
145-
logIt('Successfully logged on to Code Time');
146-
147-
return updatedUserInfo;
148-
}
149-
150-
export async function userDeletedCompletionHandler() {
151-
const user = await getUser();
152-
if (!user?.registered) {
153-
// reset the user session
154-
createAnonymousUser();
155-
156-
// update the login status
157-
window.showInformationMessage(`Successfully deleted your Code Time account`);
158-
159-
try {
160-
initializeWebsockets();
161-
} catch (e: any) {
162-
logIt(`Failed to initialize websockets: ${e.message}`);
163-
}
164-
165-
// re-initialize user and preferences
166-
await getUser();
167-
168-
// fetch after logging on
169-
SummaryManager.getInstance().updateSessionSummaryFromServer();
170-
171-
if (musicTimeExtInstalled()) {
172-
setTimeout(() => {
173-
commands.executeCommand("musictime.refreshMusicTimeView")
174-
}, 1000);
175-
}
176-
177-
if (editorOpsExtInstalled()) {
178-
setTimeout(() => {
179-
commands.executeCommand("editorOps.refreshEditorOpsView")
180-
}, 1000);
181-
}
182-
183-
commands.executeCommand('codetime.refreshCodeTimeView');
184-
185-
logIt('Successfully deleted your Code Time account');
186-
}
187-
}
188-
189-
export async function getCachedIntegrations(integration_type_id: number | undefined = undefined) {
190-
const user = await getUser();
191-
if (user?.integration_connections?.length) {
192-
if (integration_type_id) {
193-
return user.integration_connections.filter(
194-
(integration: any) => integration.status === 'ACTIVE' && integration_type_id === integration.integration_type_id
195-
);
196-
} else {
197-
return user.integration_connections;
198-
}
199-
}
200-
return [];
201135
}

src/Util.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ export function humanizeMinutes(min: any) {
360360
}
361361

362362
export function showInformationMessage(message: string) {
363+
logIt(message);
363364
return window.showInformationMessage(`${message}`);
364365
}
365366

src/command-helper.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import {commands, Disposable, window, ExtensionContext} from 'vscode';
2-
import {launchWebUrl, displayReadme, setItem} from './Util';
2+
import {launchWebUrl, displayReadme, setItem, showInformationMessage} from './Util';
33
import {KpmManager} from './managers/KpmManager';
44
import {KpmItem} from './model/models';
5-
import {showExistingAccountMenu, showSignUpAccountMenu} from './menu/AccountManager';
5+
import {createAnonymousUser, showExistingAccountMenu, showSignUpAccountMenu} from './menu/AccountManager';
66
import {TrackerManager} from './managers/TrackerManager';
77
import {app_url, vscode_issues_url} from './Constants';
88
import {enableFlow, pauseFlow} from './managers/FlowManager';
@@ -12,10 +12,13 @@ import {toggleStatusBar, updateFlowModeStatusBar, updateStatusBarWithSummaryData
1212
import {launchEmailSignup, launchLogin} from './user/OnboardManager';
1313
import {CodeTimeView} from './sidebar/CodeTimeView';
1414
import { progressIt } from './managers/ProgressManager';
15+
import { LocalStorageManager } from './managers/LocalStorageManager';
16+
import { getCachedUser, reload } from './DataController';
1517

1618
export function createCommands(
1719
ctx: ExtensionContext,
18-
kpmController: KpmManager
20+
kpmController: KpmManager,
21+
storageManager: LocalStorageManager
1922
): {
2023
dispose: () => void;
2124
} {
@@ -235,5 +238,22 @@ export function createCommands(
235238
})
236239
)
237240

241+
cmds.push(
242+
commands.registerCommand('codetime.logout', async () => {
243+
const user = await getCachedUser()
244+
if (user?.registered) {
245+
// clear the storage and recreate an anon user
246+
storageManager.clearStorage();
247+
248+
// reset the user session
249+
await createAnonymousUser();
250+
251+
// update the login status
252+
showInformationMessage(`Successfully logged out of your Code Time account`);
253+
await reload()
254+
}
255+
})
256+
)
257+
238258
return Disposable.from(...cmds);
239259
}

src/extension.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import {ChangeStateManager} from './managers/ChangeStateManager';
3232
import {initializeFlowModeState} from './managers/FlowManager';
3333
import { ExtensionManager } from './managers/ExtensionManager';
3434
import { LocalStorageManager } from './managers/LocalStorageManager';
35-
import { setSessionStorageManager } from './managers/FileManager';
3635
import { setEndOfDayNotification } from './notifications/endOfDay';
3736

3837
let currentColorKind: number | undefined = undefined;
@@ -69,10 +68,12 @@ export async function activate(ctx: ExtensionContext) {
6968
initializeSession(storageManager);
7069

7170
// add the code time commands
72-
ctx.subscriptions.push(createCommands(ctx, kpmController));
71+
ctx.subscriptions.push(createCommands(ctx, kpmController, storageManager));
7372
TrackerManager.storageMgr = storageManager;
7473

75-
if (getItem("jwt")) {
74+
const jwt = getItem('jwt');
75+
76+
if (jwt) {
7677
intializePlugin();
7778
} else if (window.state.focused) {
7879
onboardInit(ctx, intializePlugin /*successFunction*/);
@@ -151,7 +152,6 @@ export function getCurrentColorKind() {
151152
}
152153

153154
function initializeSession(storageManager: LocalStorageManager) {
154-
setSessionStorageManager(storageManager);
155155
if (window.state.focused) {
156156
setItem('vscode_primary_window', getWorkspaceName());
157157
if (storageManager) storageManager.clearDupStorageKeys();

src/http/HttpClient.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,30 @@ const appApi: any = axios.create({
2424
timeout: 15000,
2525
});
2626

27-
const headers = {
28-
'X-SWDC-Plugin-Id': getPluginId(),
29-
'X-SWDC-Plugin-Name': getPluginName(),
30-
'X-SWDC-Plugin-Version': getVersion(),
31-
'X-SWDC-Plugin-OS': getOs(),
32-
'X-SWDC-Plugin-TZ': Intl.DateTimeFormat().resolvedOptions().timeZone,
33-
'X-SWDC-Plugin-Offset': getOffsetSeconds() / 60,
34-
'X-SWDC-Plugin-UUID': getPluginUuid(),
35-
'X-SWDC-Plugin-Type': 'codetime',
36-
'X-SWDC-Plugin-Editor': 'vscode',
37-
'X-SWDC-Plugin-Editor-Version': version
38-
};
39-
40-
beApi.defaults.headers.common = { ...beApi.defaults.headers.common, ...headers };
41-
appApi.defaults.headers.common = { ...appApi.defaults.headers.common, ...headers };
27+
function initializeHeaders() {
28+
if (appApi.defaults.headers.common['X-SWDC-Plugin-Id']) {
29+
return
30+
}
31+
32+
const headers = {
33+
'X-SWDC-Plugin-Id': getPluginId(),
34+
'X-SWDC-Plugin-Name': getPluginName(),
35+
'X-SWDC-Plugin-Version': getVersion(),
36+
'X-SWDC-Plugin-OS': getOs(),
37+
'X-SWDC-Plugin-TZ': Intl.DateTimeFormat().resolvedOptions().timeZone,
38+
'X-SWDC-Plugin-Offset': getOffsetSeconds() / 60,
39+
'X-SWDC-Plugin-UUID': getPluginUuid(),
40+
'X-SWDC-Plugin-Type': 'codetime',
41+
'X-SWDC-Plugin-Editor': 'vscode',
42+
'X-SWDC-Plugin-Editor-Version': version
43+
};
44+
45+
beApi.defaults.headers.common = { ...beApi.defaults.headers.common, ...headers };
46+
appApi.defaults.headers.common = { ...appApi.defaults.headers.common, ...headers };
47+
48+
beApi.defaults.headers.common = { ...beApi.defaults.headers.common, ...headers };
49+
appApi.defaults.headers.common = { ...appApi.defaults.headers.common, ...headers };
50+
}
4251

4352
export async function appGet(api: string, queryParams: any = {}) {
4453
updateOutgoingHeader();
@@ -133,6 +142,7 @@ export function isResponseOk(resp: any) {
133142
}
134143

135144
function updateOutgoingHeader(override_token: any = null) {
145+
initializeHeaders()
136146
const token = getAuthorization();
137147
if (token || override_token) {
138148
if (override_token) {

src/managers/FileManager.ts

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
1-
import { getFileNameFromPath, getSoftwareSessionFile, logIt } from '../Util';
1+
import { getFileNameFromPath, logIt } from '../Util';
22
import { LocalStorageManager } from './LocalStorageManager';
33

44
const fs = require('fs');
55
const path = require('path');
66

77
let storageMgr: LocalStorageManager | undefined = undefined;
88

9-
export function setSessionStorageManager(storageManager: LocalStorageManager) {
10-
storageMgr = storageManager;
11-
12-
// convert old storage to new storage if needed
13-
if (!storageMgr?.getValue('session_converion_complete')) {
14-
const sessionJson = getFileDataAsJson(getSoftwareSessionFile());
15-
if (sessionJson) {
16-
for (const key in sessionJson) {
17-
storageMgr?.setValue(`session_${key}`, sessionJson[key]);
18-
}
19-
}
20-
storageManager?.setValue('session_converion_complete', 'true')
9+
function getStorageManager() {
10+
if (!storageMgr) {
11+
storageMgr = LocalStorageManager.getCachedStorageManager()
2112
}
13+
return storageMgr
2214
}
2315

2416
export function getBooleanJsonItem(file: string, key: string) {
@@ -31,12 +23,11 @@ export function getBooleanJsonItem(file: string, key: string) {
3123
}
3224

3325
export function getJsonItem(file: string, key: string, defaultValue: any = '') {
34-
return storageMgr?.getValue(`${getFileNameFromPath(file)}_${key}`) || defaultValue;
26+
return getStorageManager()?.getValue(`${getFileNameFromPath(file)}_${key}`) || defaultValue;
3527
}
3628

3729
export function setJsonItem(file: string, key: string, value: any) {
38-
const new_key = `${getFileNameFromPath(file)}_${key}`;
39-
storageMgr?.setValue(new_key, value);
30+
getStorageManager()?.setValue(`${getFileNameFromPath(file)}_${key}`, value);
4031
}
4132

4233
export function getFileDataAsJson(filePath: string): any {

0 commit comments

Comments
 (0)