Skip to content
This repository was archived by the owner on May 6, 2022. It is now read-only.

Commit 27fd9d2

Browse files
committed
implemented challenge round reset interaction and logic
1 parent c98d0ba commit 27fd9d2

24 files changed

+286
-159
lines changed

assets/templates/dashboard.template.html

+36-15
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,14 @@
126126
color: ${this.cardTextColor};
127127
word-wrap: break-word;
128128
}
129-
#chart {
129+
.fullCardGroup {
130+
display: flex;
131+
flex-direction: column;
132+
justify-content: space-evenly;
133+
}
134+
.dashboardCard {
130135
position: relative;
131136
width: 758px;
132-
height: 325px;
133137
background-color: ${this.cardBackgroundColor};
134138
border-color: rgba(0,0,0,0);
135139
color: ${this.cardTextColor};
@@ -140,6 +144,12 @@
140144
margin-bottom: 20px;
141145
padding: 20px;
142146
}
147+
.chartCard {
148+
height: 325px;
149+
}
150+
.settingsCard {
151+
min-height: 100px;
152+
}
143153
#chartXMin {
144154
position: absolute;
145155
background-color: rgba(145, 158, 171, 0.5);
@@ -261,20 +271,20 @@
261271
width: 48px;
262272
display: inline-block;
263273
}
264-
.milestoneData {
274+
.cardData {
265275
display: inline-block;
266276
width: 200px;
267277
height: 50px;
268278
vertical-align: top;
269279
margin-left: 10px;
270280
}
271-
.milestoneTitle {
281+
.cardTitle {
272282
font-size: 14px;
273283
line-height: 20px;
274284
font-weight: 600;
275285
word-wrap: break-word;
276286
}
277-
.milestoneDesc {
287+
.cardDesc {
278288
font-size: 14px;
279289
line-height: 20px;
280290
color: #919EAB;
@@ -465,16 +475,27 @@ <h1>100 Days of Code Dashboard</h1>
465475
<div class="milestoneCardGroup">${this.milestoneHtml}</div>
466476
</div>
467477
</div>
468-
<div id="chart">
469-
<div id="chartTitle">Days Coded: ${this.days} days</div>
470-
<div id="chartXMin"></div>
471-
<div class="chartYLabel" style="bottom: 45px">${this.min} hr</div>
472-
<div id="chartXMid"></div>
473-
<div class="chartYLabel" style="bottom: 170px">${this.mid} hr</div>
474-
<div id="chartXMax"></div>
475-
<div class="chartYLabel" style="bottom: 295px">${this.max} hr</div>
476-
<div id="chartBarContainer">${this.barsHtml}</div>
477-
<div id="chartDateBar">${this.xAxisDates}</div>
478+
<div class="fullCardGroup">
479+
<div id="chart" class="chartCard dashboardCard">
480+
<div id="chartTitle">Days Coded: ${this.days} days</div>
481+
<div id="chartXMin"></div>
482+
<div class="chartYLabel" style="bottom: 45px">${this.min} hr</div>
483+
<div id="chartXMid"></div>
484+
<div class="chartYLabel" style="bottom: 170px">${this.mid} hr</div>
485+
<div id="chartXMax"></div>
486+
<div class="chartYLabel" style="bottom: 295px">${this.max} hr</div>
487+
<div id="chartBarContainer">${this.barsHtml}</div>
488+
<div id="chartDateBar">${this.xAxisDates}</div>
489+
</div>
490+
<div id="settingsInfo" class="dashboardCard settingsCard">
491+
<div class="settingsCardItem">
492+
<img class="logo" src="https://100-days-of-code.s3-us-west-1.amazonaws.com/restart-challenge.svg"/>
493+
<div class="cardData">
494+
<div class="cardTitle">Current challenge round</div>
495+
<div class="cardDesc">${this.currentChallengeRound}</div>
496+
</div>
497+
</div>
498+
</div>
478499
</div>
479500
</div>
480501
</body>

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"file-it": "^1.0.26",
103103
"moment-timezone": "^0.5.28",
104104
"open": "^7.0.3",
105+
"query-string": "^6.13.7",
105106
"swdc-tracker": "^1.3.3"
106107
},
107108
"extensionDependencies": [

resources/dark/refresh copy.svg

+3
Loading

resources/dark/refresh-1.svg

+3
Loading

resources/light/refresh-1.svg

+3
Loading

resources/light/refresh.svg

+3
Loading

src/extension.ts

+20-20
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@ import { createCommands } from "./utils/CommandUtil";
55
import {
66
checkMilestonesJson
77
} from "./utils/MilestonesUtil";
8-
import { checkLogsJson, syncLogs } from "./utils/LogsUtil";
9-
import { deleteLogsPayloadJson } from "./utils/LogsDbUtils";
8+
import { syncLogs } from "./utils/LogsUtil";
109
import {
1110
displayReadmeIfNotExists,
1211
isLoggedIn,
12+
getMillisSinceLastUpdate
1313
} from "./utils/Util";
1414
import { getPluginName, getVersion } from "./utils/PluginUtil";
1515
import { TrackerManager } from "./managers/TrackerManager";
1616
import { MilestoneEventManager } from "./managers/MilestoneEventManager";
1717
import { fetchSummary } from "./utils/SummaryDbUtil";
18+
import { getSummaryJsonFilePath } from "./managers/FileManager";
1819

1920
const tracker: TrackerManager = TrackerManager.getInstance();
21+
const thirty_seconds = 1000 * 30;
22+
let milestoneMgr:MilestoneEventManager;
2023

2124
// this method is called when the extension is activated
2225
export function activate(ctx: vscode.ExtensionContext) {
@@ -33,37 +36,34 @@ export function activate(ctx: vscode.ExtensionContext) {
3336

3437
export async function initializePlugin() {
3538
// checks if all the files exist
36-
checkLogsJson();
3739
checkMilestonesJson();
3840

3941
// Displays README on first launch
4042
displayReadmeIfNotExists();
4143

42-
// initialize the milestone event manager
43-
const milestoneEventMgr: MilestoneEventManager = MilestoneEventManager.getInstance();
44-
45-
// try to send payloads that weren't sent
46-
// and fetch data from the db as well
44+
// this needs to be done on any parent or child window to initiate the file event listening logic
45+
milestoneMgr = MilestoneEventManager.getInstance();
4746

47+
// initialize logs, summary, and milestone data if its the primary window
4848
if (isLoggedIn()) {
49-
50-
if (vscode.window.state.focused) {
51-
await milestoneEventMgr.fetchAllMilestones();
52-
53-
await syncLogs();
54-
55-
// session summary
56-
await fetchSummary();
49+
// This is important to initialize in order to obtain the challenge round
50+
// if its not already in memory
51+
const millisSinceUpdate = getMillisSinceLastUpdate(getSummaryJsonFilePath());
52+
if (isThresholdMet(millisSinceUpdate)) {
53+
// initialize the user summary info (challenge_round and metrics data)
54+
await fetchSummary();
55+
await syncLogs();
56+
await milestoneMgr.fetchAllMilestones();
5757
}
58-
59-
// clean up unused files
60-
deleteLogsPayloadJson();
6158
}
62-
6359
// initialize tracker
6460
tracker.init();
6561
}
6662

63+
function isThresholdMet(millisSinceUpdate) {
64+
return (millisSinceUpdate === -1 || millisSinceUpdate > thirty_seconds);
65+
}
66+
6767
export function deactivate(ctx: vscode.ExtensionContext) {
6868
// add deactivate functionality here
6969
}

src/managers/FileManager.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,19 @@ export function getSummaryJsonFilePath() {
2828
}
2929

3030
export function fetchSummaryJsonFileData(): Summary {
31+
const emptySummary:Summary = new Summary();
3132
// checks if summary JSON exists. If not populates it with base values
3233
const filepath = getSummaryJsonFilePath();
3334
if (!fs.existsSync(filepath)) {
3435
// create a blank summary
35-
fs.writeFileSync(filepath, [JSON.stringify(new Summary(), null, 2)]);
36+
fs.writeFileSync(filepath, [JSON.stringify(emptySummary, null, 2)]);
3637
}
3738

3839
try {
40+
// return the local summary
3941
return getFileDataAsJson(filepath);
4042
} catch (e) {
4143
console.log("File not found: " + filepath);
4244
}
43-
return new Summary();
45+
return emptySummary;
4446
}

src/managers/MilestoneEventManager.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { TextDocument, TextDocumentChangeEvent, window, WindowState, workspace } from "vscode";
22
import { getDayNumberFromDate } from "../utils/LogsUtil";
33
import { checkCodeTimeMetricsMilestonesAchieved, checkDaysMilestones, checkLanguageMilestonesAchieved, compareWithLocalMilestones, getTodaysLocalMilestones } from "../utils/MilestonesUtil";
4-
import { syncSummary } from "../utils/SummaryUtil";
4+
import { getCurrentChallengeRound, syncSummary } from "../utils/SummaryUtil";
55
import { getItem, isLoggedIn } from "../utils/Util";
66
import { isResponseOk, softwareGet, softwarePost } from "./HttpManager";
77

8+
const queryString = require("query-string");
9+
810
export class MilestoneEventManager {
911
private static instance: MilestoneEventManager;
1012

@@ -106,7 +108,8 @@ export class MilestoneEventManager {
106108
local_date: Math.round(millisNow / 1000) - offset_minutes * 60, // milliseconds --> seconds,
107109
offset_minutes,
108110
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
109-
milestones
111+
milestones,
112+
challenge_round: getCurrentChallengeRound()
110113
}];
111114

112115
await softwarePost("/100doc/milestones", milestoneData, getItem("jwt"));
@@ -133,10 +136,13 @@ export class MilestoneEventManager {
133136
endDate.setHours(23, 59, 59, 0);
134137

135138
// query params
136-
const start_date = Math.round(startDate.valueOf() / 1000);
137-
const end_date = Math.round(endDate.valueOf() / 1000);
139+
const qryStr = queryString.stringify({
140+
start_date: Math.round(startDate.valueOf() / 1000),
141+
end_date: Math.round(endDate.valueOf() / 1000),
142+
challenge_round: getCurrentChallengeRound()
143+
});
138144

139-
const milestoneData = await softwareGet(`/100doc/milestones?start_date=${start_date}&end_date=${end_date}`, jwt).then(resp => {
145+
const milestoneData = await softwareGet(`/100doc/milestones?${qryStr}`, jwt).then(resp => {
140146
if (isResponseOk(resp) && resp.data) {
141147
return resp.data;
142148
}
@@ -160,7 +166,11 @@ export class MilestoneEventManager {
160166
public async fetchAllMilestones(): Promise<any> {
161167
const jwt = getItem("jwt");
162168

163-
const milestoneData = await softwareGet("/100doc/milestones", jwt).then(resp => {
169+
const qryStr = queryString.stringify({
170+
challenge_round: getCurrentChallengeRound()
171+
});
172+
173+
const milestoneData = await softwareGet(`/100doc/milestones?${qryStr}`, jwt).then(resp => {
164174
if (isResponseOk(resp) && resp.data) {
165175
return resp.data;
166176
}

src/models/Log.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export class Log {
1414
public codetime_metrics: CodetimeMetrics = new CodetimeMetrics();
1515
public shared: boolean = false;
1616
public milestones: Array<number> = [];
17+
public challenge_round: number = 0;
1718
}

src/models/Summary.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export class Summary {
1414
public shares: number = 0;
1515
public languages: string[] = [];
1616
public lastUpdated: number = 0;
17+
public challenge_round: number = 1;
1718
}

src/tree/Tree100DoCProvider.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {
1313
getDoCLearnMoreButton,
1414
getDocMilestonesButton,
1515
getDoCLogsButon,
16-
getDashboardButton
16+
getDashboardButton,
17+
getChallengeRoundRestartButton
1718
} from "./TreeButtonManager";
1819
import { TrackerManager } from "../managers/TrackerManager";
1920

@@ -156,6 +157,9 @@ export class Tree100DoCProvider implements TreeDataProvider<TreeNode> {
156157
const milestoneButton: TreeNode = getDocMilestonesButton();
157158
treeItems.push(milestoneButton);
158159

160+
const challengeRestartButton: TreeNode = getChallengeRoundRestartButton();
161+
treeItems.push(challengeRestartButton);
162+
159163
return treeItems;
160164
}
161165
}

src/tree/TreeButtonManager.ts

+10
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,13 @@ export function getDocMilestonesButton() {
5757
"100doc_milestones_btn"
5858
);
5959
}
60+
61+
export function getChallengeRoundRestartButton() {
62+
return getActionButton(
63+
"Restart challenge",
64+
"Restart the challenge round",
65+
"DoC.restartChallengeRound",
66+
"refresh.svg",
67+
"100doc_learn_more_btn"
68+
);
69+
}

src/utils/CommandUtil.ts

+25
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { getUpdatedLogsHtml } from "./LogsTemplateUtil";
1818
import { TrackerManager } from "../managers/TrackerManager";
1919
import { deleteLogDay, syncLogs } from "./LogsUtil";
2020
import { MilestoneEventManager } from "../managers/MilestoneEventManager";
21+
import { YES_LABEL } from "./Constants";
22+
import { restartChallenge } from "./SummaryUtil";
2123

2224
let currentTitle: string = "";
2325

@@ -393,5 +395,28 @@ export function createCommands(): { dispose: () => void } {
393395
})
394396
);
395397

398+
cmds.push(
399+
commands.registerCommand("DoC.restartChallengeRound", () => {
400+
if (!isLoggedIn()) {
401+
displayLoginPromptIfNotLoggedIn();
402+
return;
403+
}
404+
window
405+
.showInformationMessage(
406+
"Are you sure you want to restart the challenge? Once your challenge is restarted, you will not see your stats from your previous challenge.",
407+
{
408+
modal: true
409+
},
410+
YES_LABEL
411+
)
412+
.then(selection => {
413+
if (selection === YES_LABEL) {
414+
// set the new challenge round and create a new log based on the new round val
415+
restartChallenge();
416+
}
417+
});
418+
})
419+
);
420+
396421
return Disposable.from(...cmds);
397422
}

src/utils/DashboardUtil.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path = require("path");
22
import fs = require("fs");
3-
import { getDaysLevel, getHoursLevel, getLongStreakLevel, getLinesAddedLevel } from "./SummaryUtil";
3+
import { getDaysLevel, getHoursLevel, getLongStreakLevel, getLinesAddedLevel, getCurrentChallengeRound } from "./SummaryUtil";
44
import { Summary } from "../models/Summary";
55
import { getLastSevenLoggedDays, getAllCodetimeHours, getLogDateRange } from "./LogsUtil";
66
import { getMilestoneById } from "./MilestonesUtil";
@@ -264,9 +264,9 @@ function getMilestonesHtml(recent_milestones: Array<number>): string {
264264
`\t\t\t\t<div class="milestoneCard">`,
265265
`\t\t\t\t\t<img class="logo"`,
266266
`\t\t\t\t\tsrc="${milestone.icon}">`,
267-
`\t\t\t\t\t<div class="milestoneData">`,
268-
`\t\t\t\t\t\t<div class="milestoneTitle">${milestone.title}</div>`,
269-
`\t\t\t\t\t\t<div class="milestoneDesc">${milestone.description}</div>`,
267+
`\t\t\t\t\t<div class="cardData">`,
268+
`\t\t\t\t\t\t<div class="cardTitle">${milestone.title}</div>`,
269+
`\t\t\t\t\t\t<div class="cardDesc">${milestone.description}</div>`,
270270
`\t\t\t\t\t</div>`,
271271
`\t\t\t\t</div>`
272272
].join("\n");
@@ -346,6 +346,7 @@ export function getUpdatedDashboardHtmlString(): string {
346346
}
347347

348348
const templateVars = {
349+
currentChallengeRound: getCurrentChallengeRound(),
349350
hours: formatNumber(hours),
350351
days,
351352
streaks,

src/utils/LogsDbUtils.ts

-14
This file was deleted.

0 commit comments

Comments
 (0)