Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change tab UI, fix boss page updates #11

Merged
merged 10 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"log"
"os"
"time"

"github.com/wailsapp/wails/v2/pkg/runtime"
Expand Down Expand Up @@ -53,3 +54,7 @@ func (a *App) UserData() (bootdevapi.UserData, error) {

return userData, nil
}

func (a *App) CloseApp() {
os.Exit(0)
}
16 changes: 4 additions & 12 deletions frontend/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,22 @@
import Tabs from "./components/UI/Tabs.svelte";
import { User } from "./stores/user.js";

$: loggedIn = $User.isLoggedIn;

onMount(() => {
// Attempt to log the user on mount by refreshing their
// access token
// FIXME: signing in isn't reactive and doesn't change pages
// the issue seems to be frontend related. Data is fine on backend
// but comes empty to frontend
// * Sign in works fine from file though
LoginUserWithToken().then((result) => ($User.isLoggedIn = result));
UserData().then((result) => ($User.userData = result));
console.log("userdata", $User.userData);
});
</script>

<main>
{#if loggedIn}
{#if $User.isLoggedIn}
<Tabs />
{/if}
{#if !$User.isLoggedIn || typeof $User.isLoggedIn != "boolean"}
{:else if !$User.isLoggedIn && $User.userData.Handle !== ""}
<div class="container-buddy">
<div class="menu-container">
<!-- show user login button if automatic sign in fails -->
<Login loggedIn={$User.isLoggedIn} />
<Login bind:loggedIn={$User.isLoggedIn} />
</div>
</div>
{/if}
Expand All @@ -43,6 +35,6 @@
}

main {
padding: 1em 0 0 1em;
padding: 1em;
}
</style>
21 changes: 20 additions & 1 deletion frontend/src/components/Login.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
<script>
import { LoginUserWithOTP } from "../../wailsjs/go/main/App.js";
export let loggedIn;

// Empty field initially for the one-time password
let otpField = "";

let error = "";

// handles launching URLs outside of the app
function openBrowserLink(url) {
// @ts-ignore
window.runtime.BrowserOpenURL(url);
}

// loginUser takes a user's OTP, trades it for an access token which
// is saved for futher use, and marks the user as logged in
function loginUser() {
Expand All @@ -24,7 +31,13 @@
<a
href="https://www.boot.dev/cli/login?redirect=/cli/login"
target="_blank"
class="text-primary-500">click here</a
class="text-primary-500"
on:click={(e) => {
e.preventDefault();
openBrowserLink(
"https://www.boot.dev/cli/login?redirect=/cli/login",
);
}}>click here</a
>
to get your one-time password.
</p>
Expand All @@ -34,6 +47,12 @@
href="https://github.com/ellielle/bootdev-buddy#logging-in"
target="_blank"
class="text-primary-500"
on:click={(e) => {
e.preventDefault();
openBrowserLink(
"https://github.com/ellielle/bootdev-buddy#logging-in",
);
}}
>
be found here</a
>.
Expand Down
44 changes: 35 additions & 9 deletions frontend/src/components/UI/Tabs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@
import Courses from "../content/Courses.svelte";
import { Tab, TabGroup } from "@skeletonlabs/skeleton";
import { User } from "../../stores/user";
import { LogoutUser, CloseApp } from "../../../wailsjs/go/main/App.js";

/** @type number */
let tabSet = 0;
let tabs = ["General", "Courses", "Stats", "Boss Battle", "Archmages"];
let result;

// Setting some convenience variables so it is easier to follow
$: level = $User.userData.Level;
$: currentXP = $User.userData.XPForLevel;
$: levelXP = $User.userData.XPTotalForLevel;
$: image = $User.userData.ProfileImageURL;
$: handle = $User.userData.Handle;
function handleSignout() {
LogoutUser().then((res) => (result = res));
$User.isLoggedIn = false;
$User.isArchmage = false;
$User.userData = {};
}

function handleClose() {
CloseApp();
}
</script>

<main>
Expand Down Expand Up @@ -55,11 +61,31 @@
</svelte:fragment>

<!-- user profile and level -->
<div style="display: flex;">
<div class="flex ml-auto">
{#if $User.isLoggedIn}
<XPMeter {level} {currentXP} {levelXP} />
<Avatar {image} {handle} />
<div class="mr-3">
<XPMeter
bind:level={$User.userData.Level}
bind:currentXP={$User.userData.XPForLevel}
levelXP={$User.userData.XPTotalForLevel}
/>
</div>
<div class="mr-3">
<Avatar
bind:image={$User.userData.ProfileImageURL}
bind:handle={$User.userData.Handle}
/>
</div>
{/if}

<!-- sign out button -->
<div class="mr-3 items-center">
<button on:click={handleSignout}>Sign out</button>
</div>

<div>
<button on:click={handleClose}>✗</button>
</div>
</div>
</TabGroup>
</main>
2 changes: 1 addition & 1 deletion frontend/src/components/UI/XPMeter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<div class="xp-background-div flex bg-gray-700">
<div
class="xp-foreground-div bg-primary-500"
style="width: {levelXP / currentXP}%;"
style="width: {(currentXP / levelXP) * 100}%;"
></div>
</div>
</section>
Expand Down
74 changes: 45 additions & 29 deletions frontend/src/components/content/BossBattle.svelte
Original file line number Diff line number Diff line change
@@ -1,84 +1,100 @@
<script>
import { onMount } from "svelte";
import { BossBattle } from "../../../wailsjs/go/main/App.js";

let boss = {};

let promise = BossBattle().then((result) => (boss = result));
function fetchBossUpdate() {
BossBattle().then((result) => (boss = result));
}

onMount(() => {
BossBattle().then((result) => (boss = result));
const refreshInterval = setInterval(() => {
fetchBossUpdate();
}, 5000);

return () => {
clearInterval(refreshInterval);
};
});
</script>

<main class="flex flex-col mx-auto">
{#await promise}
{#if Object.keys(boss).length === 0}
<p>Loading...</p>
{:then battle}
<!-- FIXME: fix condition that checks for a boss defeat || new Date(battle.Event.DefeatedAt) < new Date(Date.now())-->
{#if new Date(battle.Event.ExpiresAt) < new Date(Date.now())}
{:else}
<!-- FIXME: fix condition that checks for a boss defeat -->
{#if new Date(boss.Event.ExpiresAt) < new Date(Date.now())}
<!-- boss is inactive, show stats -->
<a
href="https://www.boot.dev/lore/{battle.Event.Boss.LoreSlug}"
class="text-primary-500"
target="_blank"
>
{battle.Event.Boss.Name}
</a>
has been defeated!
<p>You gained {battle.XPUser} XP during the fight.</p>
<div>
<a
href="https://www.boot.dev/lore/{boss.Event.Boss.LoreSlug}"
class="text-primary-500"
target="_blank"
>
{boss.Event.Boss.Name}
</a>
has been defeated!
</div>
<p>You gained {boss.XPUser} XP during the fight.</p>
<p>
The final blow was dealt on {new Date(
battle.Event.DefeatedAt,
boss.Event.DefeatedAt,
).toLocaleDateString()}.
</p>
{:else}
<!-- boss is active, show a slowed feed and stats -->
<div>
<img
src={battle.Event.Boss.ImageURL}
src={boss.Event.Boss.ImageURL}
alt="Boss fight"
height="auto"
width="100%"
/>
</div>
<h1 class="text-xl my-4 text-center">{battle.Event.Boss.Name}</h1>
<h1 class="text-xl my-4 text-center">{boss.Event.Boss.Name}</h1>
<p>
{battle.Event.Boss.Description}
{boss.Event.Boss.Description}
</p>
<h2 class="mt-8 mb-4 text-center">
The battle against {battle.Event.Boss.Name} has begun!
The battle against {boss.Event.Boss.Name} has begun!
</h2>
<section class="boss-bar">
<div class="boss-background-div">
<div
class="boss-foreground-div bg-error-500"
style="width: {100 -
(battle.XPTotal / battle.Event.Boss.HealthPoints) * 100}%;"
(boss.XPTotal / boss.Event.Boss.HealthPoints) * 100}%;"
>
<div class="xp-text align-center justify-center mb-12">
{(
100 -
(battle.XPTotal / battle.Event.Boss.HealthPoints) * 100
(boss.XPTotal / boss.Event.Boss.HealthPoints) * 100
).toFixed(0)}%
</div>
</div>
</div>
</section>

Reward 1: {battle.Event.Boss.Rewards[0].UnlockedAt}
<section>
<div>
Damage dealt by the arcanum: {battle.XPTotal}
Damage dealt by the arcanum: {boss.XPTotal}
</div>
<div>
Damage dealt by you: {battle.XPUser} / 5000 xp
Damage dealt by you: {boss.XPUser} / 5000 required to qualify.
</div>
{#each battle.Event.Boss.Rewards as reward (reward.UUID)}
{#each boss.Event.Boss.Rewards as reward (reward.UUID)}
<div>
Reward: {reward.UnlockedAt} : {battle.XPTotal > reward.UnlockedAt
? "🟢"
: "❌"}
Reward at {reward.UnlockedAt} damage: {boss.XPTotal >
reward.UnlockedAt
? "✓"
: "✗"}
</div>
{/each}
</section>
{/if}
{/await}
{/if}
</main>

<style>
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/components/content/Courses.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
// once the courses array is populated
// Then set init to true to swap from loading state
$: if (courses.length > 0) {
init = false;
for (let i = 0; i < COURSES_IN_ORDER.length; i++) {
for (let j = 0; j < courses.length; j++) {
if (COURSES_IN_ORDER[i].UUID === courses[j].UUID) {
Expand All @@ -95,6 +96,7 @@
console.log("progress: ", progress.Progress);
}

// handles launching URLs outside of the app
function openBrowserLink(url) {
// @ts-ignore
window.runtime.BrowserOpenURL(url);
Expand All @@ -114,11 +116,14 @@
<div>
<!-- TODO: cursor change on hover fix it -->
<a
href="https://www.boot.dev/lessons/{course.slug}"
href="https://www.boot.dev/lessons/{progress.Progress[course.UUID]
.LastViewedLessonUUID}"
class="text-primary-500 cursor-pointer"
on:click={(e) => {
e.preventDefault();
openBrowserLink(`https://www.boot.dev/learn/${course.Slug}`);
openBrowserLink(
`https://www.boot.dev/lessons/${progress.Progress[course.UUID].LastViewedLessonUUID}`,
);
}}
>
{course.Title}:
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/components/content/General.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<script>
import { User } from "../../stores/user";
$: username = $User.userData.DiscordUserHandle;
</script>

<main>
{console.log($User)}
Welcome to Boot.dev Buddy, {username}!
Welcome to Boot.dev Buddy, {$User.userData.DiscordUserHandle}!
</main>
34 changes: 19 additions & 15 deletions frontend/src/components/content/Stats.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,23 @@
</script>

<main>
{#each Object.entries(stats) as stat}
<div>
{generalStats[stat[0]] + ": " + stat[1]}
</div>
{/each}
{#each archons as sage}
<div>
{sage?.Handle}
</div>
{/each}
{#each leaders as lead}
<div>
{lead?.Handle}
</div>
{/each}
{#if false}
{#each Object.entries(stats) as stat}
<div>
{generalStats[stat[0]] + ": " + stat[1]}
</div>
{/each}
{#each archons as sage}
<div>
{sage?.Handle}
</div>
{/each}
{#each leaders as lead}
<div>
{lead?.Handle}
</div>
{/each}
{:else}
Under work
{/if}
</main>
Loading
Loading