Skip to content

Commit

Permalink
feat: optimize the code and add splash screen
Browse files Browse the repository at this point in the history
  • Loading branch information
fu050409 committed Dec 4, 2024
1 parent 0bf2284 commit 0f643f9
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changes/splash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"algohub": patch:feat
---

Add splash screen before loading index page.
2 changes: 1 addition & 1 deletion src/components/MonacoEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const onSubmit = () => {
emit(
'submit',
rawEditor.value.getValue(),
language,
language.value,
(text: string, severity: Severity) => {
submitting.value = false
message.value = { text, severity }
Expand Down
88 changes: 88 additions & 0 deletions src/components/SplashScreen.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import * as api from "@/scripts/api";
import { useAccountStore } from '@/scripts/store';
import { useRouter } from 'vue-router';
const loading = defineModel<boolean>({ required: true })
const router = useRouter();
const texts = [
"Welcome to AlgoHub",
"Be true to your true self, not to your ego. Choose the normalcy, not human kind. \
Believe in civilization, not humanity."
]
const index = ref(0);
const status = ref("Loading...");
const onChange = () => {
index.value = (index.value + 1) % texts.length;
}
const accountStore = useAccountStore();
export interface LatestVersions {
nightly?: string;
stable?: string;
alpha?: string;
beta?: string;
rc?: string;
status: boolean;
}
onMounted(async () => {
status.value = "Checking for updates...";
try {
const { invoke } = (await import('@tauri-apps/api/core'));
const versions: LatestVersions = await invoke("get_latest_versions");
if (!versions.status) {
status.value = "Failed to get latest versions, skipping update check..."
} else {
if (versions.beta) {
status.value = `New beta version available: ${versions.beta}`;
} else {
status.value = `The latest alpha version is: ${versions.alpha}, no available updates.`
}
await new Promise(resolve => setTimeout(resolve, 3000));
}
} catch (e) {
console.error(e);
status.value = "Tauri API not found, skipping update check..."
await new Promise(resolve => setTimeout(resolve, 3000));
}
status.value = "Checking for login...";
if (accountStore.isLoggedIn) {
const res = await api.verifyToken(accountStore.auth);
if (!res.success) {
accountStore.logout();
status.value = "User credentials expired. Consider login again.";
await new Promise(resolve => setTimeout(resolve, 3000));
loading.value = false;
router.push('/login')
} else {
loading.value = false;
router.push('/dashboard')
}
}
loading.value = false;
})
</script>

<template>
<div @click="onChange" class="bg-gray-900 flex flex-col items-center justify-center h-full w-full">
<div class="flex flex-col items-center justify-center h-full w-full max-w-[700px] gap-[2em]">
<div class="flex flex-col items-center justify-center">
<img src="/acm-light.png" class="w-48" />
<div class=" text-white text-center font-bold text-4xl w-full">AlgoHub
</div>
</div>
<div class="flex flex-col gap-3 justify-center w-full px-20">
<div class="text-sm mb-5">{{ texts[index] }}</div>
<ProgressBar mode="indeterminate" class="w-full !h-[5px]"></ProgressBar>
<div class="text-gray-500 text-right font-bold text-sm">{{ status }}</div>
</div>
</div>
<div class="flex flex-col text-center w-full text-xs mb-10">
<span>Copyright © 2006-present ACM-SWPU. All rights reserved.</span>
</div>
</div>
</template>
37 changes: 36 additions & 1 deletion src/scripts/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import type {
Profile,
UserContent,
CreateProblem,
Language,
RecordId,
} from "./types";

export interface Response<D> {
Expand Down Expand Up @@ -79,6 +81,15 @@ export const login = async (form: Login) => {
}
};

export const verifyToken = async (auth?: Credentials) => {
try {
const response = await axios.post("/account/verify", auth);
return response.data as Response<Credentials>;
} catch (error) {
return handleAxiosError(AxiosError.from(error));
}
};

export const fetchProfile = async (id: string) => {
try {
const response = await axios.get(`/account/profile/${id}`);
Expand Down Expand Up @@ -131,10 +142,34 @@ interface SubmitCodeForm {
lang: string;
}

interface Id {
id: string;
}

export const submitCode = async (problem_id: string, form: SubmitCodeForm) => {
try {
const response = await axios.post(`/code/submit/${problem_id}`, form);
return response.data as Response<undefined>;
return response.data as Response<Id>;
} catch (error) {
return handleAxiosError(AxiosError.from(error));
}
};

interface Submission {
id: string;
lang: Language;
problem: RecordId;
code: string;
status: 'in_queue' | 'judging' | 'ready';
judge_details: { status: any, timeUsed: number, memoryUsed: number }[],
judge_result: { status: any, timeUsed: number, memoryUsed: number },
// contest
}

export const fetchSubmission = async (id: string, form?: Credentials) => {
try {
const response = await axios.post(`/code/get/${id}`, form);
return response.data as Response<Submission>;
} catch (error) {
return handleAxiosError(AxiosError.from(error));
}
Expand Down
14 changes: 6 additions & 8 deletions src/views/index.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
<script setup lang="ts">
import { useAccountStore } from '@/scripts/store';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const accountStore = useAccountStore();
if (accountStore.isLoggedIn) {
router.push('/dashboard');
}
const loading = ref(true);
</script>

<template>
<div
<SplashScreen v-if="loading" v-model="loading" />
<div v-if="!loading"
class="fixed bottom-0 sm:bottom-unset w-full py-2 bg-indigo-600 text-white sm:flex sm:items-center sm:justify-between sm:px-6 lg:px-8">
<p class="text-center font-medium sm:text-left">
AlgoHub is on nightly build now! Want to try it out?
AlgoHub is on alpha now! Want to try it out?
<br class="sm:hidden" />
See the latest updates!
</p>
Expand All @@ -24,7 +22,7 @@ if (accountStore.isLoggedIn) {
Releases
</a>
</div>
<section class="bg-gray-900 text-white h-screen w-full">
<section v-if="!loading" class="bg-gray-900 text-white h-screen w-full">
<div class="mx-auto max-w-screen-xl px-4 py-32 lg:flex lg:h-screen lg:items-center">
<div class="mx-auto max-w-3xl text-center">
<h1
Expand Down
64 changes: 50 additions & 14 deletions src/views/problem/[id].vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { onMounted, onUnmounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import * as api from '@/scripts/api';
import { useAccountStore, useThemeStore } from '@/scripts/store';
Expand Down Expand Up @@ -33,7 +33,7 @@ const formatProblem = (problem: UserProblem) => {
}
hint && (formattedText += `## Hint\n\n${hint}\n\n`);
return formattedText;
return formattedText.repeat(10);
}
const code = ref('');
Expand All @@ -53,7 +53,12 @@ const onSubmit = async (code: string, lang: Language, finish: (text: string, sev
if (!res.success) {
return finish(res.message, 'error');
}
finish('Code submitted', 'success');
await new Promise(resolve => setTimeout(resolve, 2000));
const submission = await api.fetchSubmission(res.data!.id, accountStore.auth!);
if (!submission.success) {
return finish(submission.message, 'error');
}
finish(submission.data!.judge_result.status, 'success');
}
const path = ref<{ label?: string, link?: string }[]>([]);
Expand All @@ -74,24 +79,49 @@ onMounted(async () => {
]
loading.value = false;
})
const windowWidth = ref(window.innerWidth);
window.onresize = () => {
windowWidth.value = window.innerWidth;
}
onUnmounted(() => {
window.onresize = null;
})
</script>

<template>
<div class="flex flex-col h-full">
<UniversalToolBar :path></UniversalToolBar>
<Splitter :gutterSize="2" class="flex-1 overflow-hidden">
<Splitter :gutterSize="2" class="flex-1 overflow-hidden"
:layout="windowWidth > 768 ? 'horizontal' : 'vertical'">
<SplitterPanel>
<Panel class="w-full h-full overflow-auto" pt:header:class="!hidden">
<MdPreview v-if="!loading" class="!bg-transparent" :modelValue="formatProblem(problem!)"
:theme="themeStore.dark ? 'dark' : 'light'" codeTheme="github" previewTheme="github">
</MdPreview>
<div v-else class="flex flex-col gap-4 m-3">
<Skeleton height="2em" width="15vw"></Skeleton>
<Skeleton height="5em" width="40vw"></Skeleton>
<Skeleton height="2em" width="30vw"></Skeleton>
<Skeleton height="10em" width="40vw"></Skeleton>
<div class="flex flex-col gap-2 w-full h-full">
<div class="p-3 flex flex-wrap flex-row items-center justify-between w-full">
<Button size="small" icon="pi pi-arrow-left" plain outlined></Button>
<div class="inline-flex items-center gap-1">
<Button icon="pi pi-pencil" size="small" plain outlined></Button>
<Button size="small" severity="danger" icon="pi pi-trash" outlined></Button>
</div>
</div>
<div class="flex flex-row w-full h-full">
<div class="flex flex-col w-20 gap-4">
<Button pt:label:class="text-xs" label="Problem" icon="pi pi-code" size="small"
iconPos="top" plain text disabled></Button>
<Button pt:label:class="text-xs" label="Records" icon="pi pi-file" size="small"
iconPos="top" plain text disabled></Button>
</div>
<MdPreview v-if="!loading" class="!bg-transparent" :modelValue="formatProblem(problem!)"
:theme="themeStore.dark ? 'dark' : 'light'" codeTheme="github" previewTheme="github">
</MdPreview>
<div v-else class="flex flex-col gap-4 m-3">
<Skeleton height="2em" width="15vw"></Skeleton>
<Skeleton height="5em" width="40vw"></Skeleton>
<Skeleton height="2em" width="30vw"></Skeleton>
<Skeleton height="10em" width="40vw"></Skeleton>
</div>
</div>
</Panel>
</div>
</SplitterPanel>
<SplitterPanel>
<MonacoEditor :code="code" :language="language" :onSubmit>
Expand All @@ -100,3 +130,9 @@ onMounted(async () => {
</Splitter>
</div>
</template>

<style scoped>
:deep(.md-editor-preview-wrapper) {
padding: 0 1em 0 1em;
}
</style>

0 comments on commit 0f643f9

Please sign in to comment.