Landing page redacted!
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 17s
All checks were successful
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Successful in 17s
This commit is contained in:
parent
07f0d798a2
commit
4205712d32
5 changed files with 53 additions and 44 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
import fly from "@e/fly";
|
import fly from "@e/fly";
|
||||||
import MediaQuery from "svelte-media-queries";
|
import MediaQuery from "svelte-media-queries";
|
||||||
import Dices from "@lucide/svelte/icons/dices";
|
import Dices from "@lucide/svelte/icons/dices";
|
||||||
import { re } from "@ts/Redaction/Redactor";
|
import re from "@ts/Redaction/Redactor";
|
||||||
let hideOnPrint: boolean = $state(false);
|
let hideOnPrint: boolean = $state(false);
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
@ -115,16 +115,14 @@
|
||||||
</a>
|
</a>
|
||||||
<div class="nav-spacer" />
|
<div class="nav-spacer" />
|
||||||
|
|
||||||
<!-- <a href="/">Home</a> -->
|
|
||||||
<!-- <a href="/zhen/notes/physics/1?hideOnPrint=1" target="_blank" style="width: 7.5rem;">Notes</a> -->
|
|
||||||
|
|
||||||
{@render SwitchThemeButton()}
|
{@render SwitchThemeButton()}
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="/cv?hideOnPrint=1"
|
href="/cv?hideOnPrint=1"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
style="width: 7.5rem;"
|
style="width: 7.5rem;"
|
||||||
class="text-center justify-center">Zhen CV</a
|
class="text-center justify-center text-md"
|
||||||
|
>{$re?.nick ?? "Alex"}'s CV</a
|
||||||
>
|
>
|
||||||
<!-- <a href="/tools" style="width: 7.5rem;" class="text-center">Tools</a> -->
|
<!-- <a href="/tools" style="width: 7.5rem;" class="text-center">Tools</a> -->
|
||||||
<a href="https://botalex.itch.io/" target="_blank">Games</a>
|
<a href="https://botalex.itch.io/" target="_blank">Games</a>
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,9 @@
|
||||||
// import NameAndTag from "./comps/NameAndTag.svelte";
|
// import NameAndTag from "./comps/NameAndTag.svelte";
|
||||||
import Profile from "./comps/Profile.svelte";
|
import Profile from "./comps/Profile.svelte";
|
||||||
import DeprivedTrackerSection from "./comps/DeprivedTrackerSection.svelte";
|
import DeprivedTrackerSection from "./comps/DeprivedTrackerSection.svelte";
|
||||||
|
import re from "@src/ts/Redaction/Redactor";
|
||||||
|
|
||||||
const mobileThreshold: string = "600px"; // was 1000px. zhen testing
|
const mobileThreshold: string = "600px"; // was 1000px.
|
||||||
let mobile: boolean;
|
let mobile: boolean;
|
||||||
let debug = false;
|
let debug = false;
|
||||||
|
|
||||||
|
|
@ -102,14 +103,15 @@
|
||||||
class="grid max-lg:grid-cols-1 sm:grid-cols-2 gap-4 p-4 max-lg:px-0 w-full"
|
class="grid max-lg:grid-cols-1 sm:grid-cols-2 gap-4 p-4 max-lg:px-0 w-full"
|
||||||
>
|
>
|
||||||
<Profile
|
<Profile
|
||||||
name="Zhen / Alex"
|
name={$re?.nick ? $re?.nick + "/Alex" : "Alex"}
|
||||||
tags={["Programmer", "3D artist", "UX Designer"]}
|
tags={["Programmer", "3D artist", "UX Designer"]}
|
||||||
isMobile={mobile}
|
isMobile={mobile}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<p>
|
<p>
|
||||||
Hi, I am Alex/Zhen, {@html !mobile ? "" : "<br/>"} I'm that chinese
|
Hi, I am {$re?.nick ? $re?.nick + "/Alex" : "Alex"}, {@html !mobile
|
||||||
guy.
|
? ""
|
||||||
|
: "<br/>"} I'm that chinese guy.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Here's my CV: <a href="/cv?hideOnPrint=1" style="color:lightblue;"
|
Here's my CV: <a href="/cv?hideOnPrint=1" style="color:lightblue;"
|
||||||
|
|
@ -203,7 +205,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="py-4"></div>
|
<div class="py-4"></div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="grid place-content-center place-items-center pointer-events-auto font-mono"
|
class="grid place-content-center place-items-center pointer-events-auto font-mono"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
import onDestroy from "@e/onDestroy";
|
import onDestroy from "@e/onDestroy";
|
||||||
import ArrowBigDown from "lucide-svelte/icons/arrow-big-down";
|
import ArrowBigDown from "lucide-svelte/icons/arrow-big-down";
|
||||||
import fly from "@e/fly";
|
import fly from "@e/fly";
|
||||||
|
import re from "@ts/Redaction/Redactor";
|
||||||
const buildTime = __BUILD_TIME__;
|
const buildTime = __BUILD_TIME__;
|
||||||
|
|
||||||
let scrollY = 0;
|
let scrollY = 0;
|
||||||
|
|
@ -156,16 +157,16 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="{hideOnPrint ? 'hide-on-print' : ''} w-full">
|
<div class="{hideOnPrint ? 'hide-on-print' : ''} w-full">
|
||||||
<!-- Keep scrolling thing -->
|
<!-- <!-- Keep scrolling thing --> -->
|
||||||
<div class="hidden h-64 w-full flex flex-col justify-center items-center">
|
<!-- <div class="hidden h-64 w-full flex flex-col justify-center items-center"> -->
|
||||||
<div>Keep scrolling to veiw Zhen's portfolio site!</div>
|
<!-- <div>Keep scrolling to veiw [Redacted]'s portfolio site!</div> -->
|
||||||
<div class="flex justify-center">
|
<!-- <div class="flex justify-center"> -->
|
||||||
<ArrowBigDown />
|
<!-- <ArrowBigDown /> -->
|
||||||
<ArrowBigDown />
|
<!-- <ArrowBigDown /> -->
|
||||||
<ArrowBigDown />
|
<!-- <ArrowBigDown /> -->
|
||||||
<ArrowBigDown />
|
<!-- <ArrowBigDown /> -->
|
||||||
</div>
|
<!-- </div> -->
|
||||||
</div>
|
<!-- </div> -->
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="hidden h-64 w-full flex flex-col justify-end items-center"
|
class="hidden h-64 w-full flex flex-col justify-end items-center"
|
||||||
|
|
@ -193,7 +194,7 @@
|
||||||
<br />
|
<br />
|
||||||
<span>Snorre Ettrup Altschul</span>
|
<span>Snorre Ettrup Altschul</span>
|
||||||
<br />
|
<br />
|
||||||
<span>Zhentao Wei</span>
|
<span>{$re?.name ?? "BOT Alex"}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<h3><b>About this website</b></h3>
|
<h3><b>About this website</b></h3>
|
||||||
|
|
@ -221,7 +222,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<h3><b>Contact</b></h3>
|
<h3><b>Contact</b></h3>
|
||||||
<a href="mailto:zhen@deprived.dev">zhen@deprived.dev</a>
|
<a href="mailto:{$re?.email ?? 'Alex@deprived.dev'}"
|
||||||
|
>{$re?.email ?? "alex@deprived.dev"}</a
|
||||||
|
>
|
||||||
<div class="mt-2"></div>
|
<div class="mt-2"></div>
|
||||||
<a
|
<a
|
||||||
href="https://discord.gg/awatEEqc3M"
|
href="https://discord.gg/awatEEqc3M"
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ const EducationLoose = z.object({
|
||||||
|
|
||||||
const ProfileSchema = z.object({
|
const ProfileSchema = z.object({
|
||||||
name: z.string().min(1),
|
name: z.string().min(1),
|
||||||
|
nick: z.string().min(1),
|
||||||
shortProfileHiddenContent: z.array(z.string()),
|
shortProfileHiddenContent: z.array(z.string()),
|
||||||
email: z.string().email(),
|
email: z.string().email(),
|
||||||
phone: z.string().min(1),
|
phone: z.string().min(1),
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,62 @@
|
||||||
|
// redactor.ts
|
||||||
import { parseProfile, type Profile } from "./Profile";
|
import { parseProfile, type Profile } from "./Profile";
|
||||||
import env from "@ts/EnvHandler";
|
import env, { initEnv } from "@ts/EnvHandler";
|
||||||
import { initEnv } from "@ts/EnvHandler";
|
import type { Readable, Subscriber, Unsubscriber } from "svelte/store";
|
||||||
|
|
||||||
class Redactor {
|
class Redactor implements Readable<Profile | undefined> {
|
||||||
public unredactedProfile: Profile | undefined = undefined;
|
public unredactedProfile: Profile | undefined = undefined;
|
||||||
|
|
||||||
|
private subs = new Set<Subscriber<Profile | undefined>>();
|
||||||
|
subscribe(run: Subscriber<Profile | undefined>): Unsubscriber {
|
||||||
|
this.subs.add(run);
|
||||||
|
run(this.unredactedProfile);
|
||||||
|
return () => this.subs.delete(run);
|
||||||
|
}
|
||||||
|
private notify() {
|
||||||
|
this.subs.forEach((s) => s(this.unredactedProfile));
|
||||||
|
}
|
||||||
|
|
||||||
async TryGetUnredacter(): Promise<Profile> {
|
async TryGetUnredacter(): Promise<Profile> {
|
||||||
if (!!this.unredactedProfile) return this.unredactedProfile;
|
if (this.unredactedProfile) return this.unredactedProfile;
|
||||||
|
|
||||||
const storedKey = localStorage.getItem("key");
|
const storedKey = localStorage.getItem("key");
|
||||||
if (!storedKey) throw new Error("Missing key");
|
if (!storedKey) throw new Error("Missing key");
|
||||||
|
|
||||||
let jsonKey = JSON.stringify({ key: storedKey });
|
|
||||||
console.log("Requesting unredactor.json with: " + jsonKey);
|
|
||||||
|
|
||||||
const hashResJson = await (
|
const hashResJson = await (
|
||||||
await fetch("https://api.deprived.dev/unredact", {
|
await fetch("https://api.deprived.dev/unredact", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: jsonKey,
|
body: JSON.stringify({ key: storedKey }),
|
||||||
})
|
})
|
||||||
).json();
|
).json();
|
||||||
|
|
||||||
const unredactHash = hashResJson.response;
|
const unredactHash = hashResJson.response;
|
||||||
console.log('Trying unredact hash: "' + unredactHash + '"');
|
|
||||||
|
|
||||||
initEnv();
|
initEnv();
|
||||||
const url = `${env.POCKETBASE_URL}/api/files/redacted_content/${unredactHash}/redacted_cv_info_ha08bbn520.json`;
|
const url = `${env.POCKETBASE_URL}/api/files/redacted_content/${unredactHash}/redacted_cv_info_amhz90nhr7.json`;
|
||||||
|
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: { Accept: "application/json" },
|
headers: { Accept: "application/json" },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||||
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
return parseProfile(data);
|
this.unredactedProfile = parseProfile(data);
|
||||||
|
this.notify(); // <-- tell Svelte to update
|
||||||
|
return this.unredactedProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
async t(unredactPath: string, fallback: string): Promise<string> {
|
t(path: string, fallback: string): string {
|
||||||
try {
|
try {
|
||||||
if (!this.unredactedProfile) await this.TryGetUnredacter();
|
const src = this.unredactedProfile as Record<string, unknown> | undefined;
|
||||||
const src = this.unredactedProfile ?? {};
|
if (!src) return fallback;
|
||||||
|
const v = path.split(".").reduce<any>((o, k) => (o as any)?.[k], src);
|
||||||
// safe dot-path lookup
|
return (v ?? "") !== "" ? String(v) : fallback;
|
||||||
const value = unredactPath.split(".").reduce<any>((o, k) => o?.[k], src);
|
|
||||||
|
|
||||||
return (value ?? "") !== "" ? String(value) : fallback;
|
|
||||||
} catch {
|
} catch {
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let re = new Redactor();
|
export const re = new Redactor();
|
||||||
|
export default re;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue