Skip to content

Commit

Permalink
Merge pull request #4 from uhKayla/dev
Browse files Browse the repository at this point in the history
Add worlds page & search functionality
  • Loading branch information
kay-xr authored Jun 25, 2024
2 parents 2fa1f98 + efed9aa commit 035593f
Show file tree
Hide file tree
Showing 27 changed files with 838 additions and 8 deletions.
46 changes: 46 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@
"@tauri-apps/api": "^1.5.6",
"bits-ui": "^0.21.10",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"js-base64": "^3.7.7",
"lucide-svelte": "^0.395.0",
"mode-watcher": "^0.3.1",
"node-fetch": "^3.3.2",
"p-limit": "^5.0.0",
"svelte-legos": "^0.2.3",
"svelte-sonner": "^0.3.24",
"tailwind-merge": "^2.3.0",
"tailwind-variants": "^0.2.1"
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"package": {
"productName": "SpectreVRC",
"version": "0.1.5"
"version": "0.1.6"
},
"tauri": {
"allowlist": {
Expand Down
122 changes: 118 additions & 4 deletions src/lib/components/Footer.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,125 @@
<script lang="ts">
import { user } from '$lib/stores/user';
import type { UserData } from '$lib/types/user';
import { goto } from '$app/navigation';
import { getUsersOnline } from '$lib/utils/getUsersOnline';
import { onMount } from 'svelte';
import { getApiTime } from '$lib/utils/getApiTime';
let onlineFriendsCount = 0;
let onlineUsers = 0;
let dateTime: string = '';
let currentTime: string = 'Loading...';
user.subscribe((userData: UserData | null) => {
if (userData) {
onlineFriendsCount = userData.onlineFriends.length;
}
});
function cleanDateTimeString(dateTime: string): string {
// Remove any extraneous quotes and trim the string
return dateTime.replace(/(^")|("$)/g, '').trim();
}
function updateCurrentTime(initialDateTime: string) {
try {
const cleanedDateTime = cleanDateTimeString(initialDateTime);
const date = new Date(cleanedDateTime);
if (isNaN(date.getTime())) {
throw new Error('Invalid Date');
}
const now = new Date();
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
date.setSeconds(date.getSeconds() + diffInSeconds);
currentTime = date.toLocaleTimeString();
} catch (error) {
console.error('Error updating current time:', error);
currentTime = 'Invalid Date';
}
}
onMount(async () => {
try {
onlineUsers = await getUsersOnline();
dateTime = await getApiTime();
if (!dateTime) {
throw new Error('Invalid dateTime fetched from API');
}
updateCurrentTime(dateTime);
setInterval(() => updateCurrentTime(dateTime), 1000);
} catch (error) {
console.error('Error on mount:', error);
}
});
</script>

<style>
.ticker-container {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.ticker-wrapper {
position: relative;
width: 30%;
overflow: hidden;
}
.ticker-wrapper::before,
.ticker-wrapper::after {
content: '';
position: absolute;
top: 0;
width: 15%;
height: 100%;
pointer-events: none;
}
.ticker-wrapper::before {
left: 0;
background: linear-gradient(to right, #09090b, transparent);
z-index: 1;
}
.ticker-wrapper::after {
right: 0;
background: linear-gradient(to left, #09090b, transparent);
}
/* ticker https://code-boxx.com/html-css-news-ticker-horizontal-vertical/*/
.hmove {
display: flex;
justify-content: space-between;
}
.hitem { width: 100%; flex-shrink: 0; }
.hwrap {
overflow: hidden;
justify-content: space-between;
}
@keyframes tickerh {
0% { transform: translatex(100%); }
100% { transform: translatex(-400%); }
}
.hmove { animation: tickerh linear 20s infinite; }
.hmove:hover { animation-play-state: paused; }
/* end ticker */
</style>

<footer class="h-10 justify-center text-center items-center object-center w-screen bg-background border-t">
<div class="font-mono">
Made with ❤️ by ANGELWARE
<footer class="h-10 flex justify-center items-center w-screen bg-background border-t">
<div class="ticker-container">
<div class="font-mono ticker-wrapper">
<div class="hwrap">
<div class="hmove">
<div class="hitem">Made with ❤️ by ANGELWARE</div>
<div class="hitem">Online Friends: {onlineFriendsCount}</div>
<div class="hitem">Online Users: {onlineUsers}</div>
<div class="hitem">VRChat Time: {currentTime}</div>
</div>
</div>
</div>
</div>
</footer>
</footer>
5 changes: 4 additions & 1 deletion src/lib/components/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<!-- src/lib/components/Header.svelte -->
<script lang="ts">
import { page } from '$app/stores';
import { toggleMode } from 'mode-watcher';
Expand Down Expand Up @@ -67,6 +66,9 @@
<!-- <a href="/feed" class:text-foreground={$page.url.pathname === '/feed'} class:text-muted-foreground={$page.url.pathname !== '/feed'} class="hover:text-foreground">-->
<!-- Feed-->
<!-- </a>-->
<a href="/worlds" class:text-foreground={$page.url.pathname === '/worlds/search'} class:text-muted-foreground={$page.url.pathname !== '/worlds'} class="hover:text-foreground">
Worlds
</a>
</nav>
<Sheet.Root>
<Sheet.Trigger asChild let:builder>
Expand All @@ -84,6 +86,7 @@
<a href="/dash" class:text-foreground={$page.url.pathname === '/dash'} class:text-muted-foreground={$page.url.pathname !== '/dash'} class="hover:text-foreground"> Dashboard </a>
<a href="/friends" class:text-foreground={$page.url.pathname === '/friends'} class:text-muted-foreground={$page.url.pathname !== '/friends'} class="hover:text-foreground"> Friends </a>
<!-- <a href="/feed" class:text-foreground={$page.url.pathname === '/feed'} class:text-muted-foreground={$page.url.pathname !== '/feed'} class="hover:text-foreground"> Feed </a>-->
<a href="/worlds" class:text-foreground={$page.url.pathname === '/worlds'} class:text-muted-foreground={$page.url.pathname !== '/worlds'} class="hover:text-foreground"> Worlds </a>
</nav>
</Sheet.Content>
</Sheet.Root>
Expand Down
57 changes: 57 additions & 0 deletions src/lib/components/WorldSearch.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script lang="ts">
import { worldSearchStore } from '$lib/stores/worldSearchStore';
import type { WorldSearchData } from '$lib/types/worldSearch.js';
import { onMount, afterUpdate } from 'svelte';
import { get } from 'svelte/store';
import { getActiveWorlds } from '$lib/utils/getActiveWorlds';
import WorldCard from '$lib/components/cards/WorldCard.svelte';
export let page: number;
let worldMap: Map<string, WorldSearchData> | null = null;
const getPageOffset = (page: number) => {
return page * 18;
};
const fetchAndStoreWorlds = async (offset: number) => {
try {
const worlds = await getActiveWorlds(offset);
const worldMap = new Map<string, WorldSearchData>();
worlds.forEach(world => {
worldMap.set(world.id, world);
});
worldSearchStore.set(worldMap);
} catch (error) {
console.error('Error fetching and storing worlds:', error);
}
};
const loadWorlds = async () => {
const offset = getPageOffset(page);
await fetchAndStoreWorlds(offset);
worldMap = get(worldSearchStore);
};
onMount(async () => {
worldMap = get(worldSearchStore);
if (!worldMap || worldMap.size < 1) {
await loadWorlds();
}
});
$: if (page !== undefined) {
loadWorlds();
}
</script>

<div>
<div class="grid grid-cols-3 p-4">
{#if worldMap && worldMap.size > 0}
{#each Array.from(worldMap.values()) as world (world.id)}
<WorldCard world={world} />
{/each}
{:else}
<p>No worlds available.</p>
{/if}
</div>
</div>
47 changes: 47 additions & 0 deletions src/lib/components/WorldSearchProp.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<script lang="ts">
import { onMount } from 'svelte';
import WorldCard from '$lib/components/cards/WorldCard.svelte';
import type { WorldSearchData } from '$lib/types/worldSearch.js';
import { getSearchWorlds } from '$lib/utils/getSearchWorlds';
export let searchString: string;
let worldMap: Map<string, WorldSearchData> | null = null;
const fetchWorlds = async (searchString: string) => {
try {
const worlds = await getSearchWorlds(searchString);
const worldMap = new Map<string, WorldSearchData>();
worlds.forEach(world => {
worldMap.set(world.id, world);
});
return worldMap;
} catch (error) {
console.error('Error fetching worlds:', error);
return null;
}
};
const loadWorlds = async () => {
worldMap = await fetchWorlds(searchString);
};
onMount(loadWorlds);
$: {
if (searchString !== undefined) {
loadWorlds();
}
}
</script>

<div>
<div class="grid grid-cols-3 p-4">
{#if worldMap && worldMap.size > 0}
{#each Array.from(worldMap.values()) as world (world.id)}
<WorldCard world={world} />
{/each}
{:else}
<p>No worlds available.</p>
{/if}
</div>
</div>
2 changes: 1 addition & 1 deletion src/lib/components/cards/CalloutCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</div>
</Card.Content>
<Card.Footer class="flex justify-center items-center">
<Button disabled>Discover Worlds</Button>
<Button href="/worlds">Discover Worlds</Button>
</Card.Footer>
</Card.Root>

Loading

0 comments on commit 035593f

Please sign in to comment.