initial commit
This commit is contained in:
54
src/App.svelte
Normal file
54
src/App.svelte
Normal file
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { Router, Link, Route } from "svelte-navigator";
|
||||
import { Form, Input } from 'sveltestrap';
|
||||
import Toggle from 'svelte-toggle';
|
||||
import Navigation from "./lib/Navigation.svelte";
|
||||
|
||||
let light = "https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css"
|
||||
let dark = "https://cdn.jsdelivr.net/npm/bootstrap-dark-5@1.1.3/dist/css/bootstrap-night.min.css"
|
||||
|
||||
let styleSrc = light;
|
||||
let style = localStorage.getItem("pk-style");
|
||||
|
||||
onMount(() => {
|
||||
setStyle(style);
|
||||
})
|
||||
|
||||
function setStyle(style) {
|
||||
switch (style) {
|
||||
case "light": styleSrc = light;
|
||||
localStorage.setItem("pk-style", "light");
|
||||
break;
|
||||
case "dark": styleSrc = dark;
|
||||
localStorage.setItem("pk-style", "dark");
|
||||
break;
|
||||
default: styleSrc = light;
|
||||
localStorage.setItem("pk-style", "light");
|
||||
};
|
||||
};
|
||||
|
||||
function styleSelect(e) {
|
||||
style = e.target.value.toLowerCase();
|
||||
setStyle(style);
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<link rel="stylesheet" href={styleSrc}>
|
||||
</svelte:head>
|
||||
|
||||
<Router>
|
||||
<Navigation/>
|
||||
<div>
|
||||
<Route path="/">
|
||||
<h2>Ooga booga</h2>
|
||||
<Form>
|
||||
<Input type="select" name="themes" id="themes" on:change={(e) => styleSelect(e)}>
|
||||
<option>Light</option>
|
||||
<option>Dark</option>
|
||||
</Input>
|
||||
</Form>
|
||||
</Route>
|
||||
</div>
|
||||
</Router>
|
36
src/api/group.ts
Normal file
36
src/api/group.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
interface GroupPrivacy {
|
||||
description_privacy?: string | boolean | null;
|
||||
icon_privacy?: string | boolean | null;
|
||||
list_privacy?: string | boolean | null;
|
||||
visibility?: string | boolean | null;
|
||||
}
|
||||
|
||||
export default class Group {
|
||||
id?: string;
|
||||
uuid?: string;
|
||||
name?: string;
|
||||
display_name?: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
banner?: string;
|
||||
color?: string;
|
||||
privacy?: GroupPrivacy;
|
||||
|
||||
constructor(data: any) {
|
||||
this.id = data.id;
|
||||
this.uuid = data.uuid;
|
||||
this.name = data.name;
|
||||
this.display_name = data.display_name;
|
||||
this.description = data.description;
|
||||
this.icon = data.icon;
|
||||
this.banner = data.banner;
|
||||
this.color = data.color;
|
||||
if (data.privacy) {
|
||||
this.privacy = {}
|
||||
this.privacy.description_privacy = data.privacy.description_privacy;
|
||||
this.privacy.icon_privacy = data.privacy.icon_privacy;
|
||||
this.privacy.list_privacy = data.privacy.list_privacy;
|
||||
this.privacy.visibility = data.privacy.visibility;
|
||||
}
|
||||
}
|
||||
}
|
176
src/api/index.ts
Normal file
176
src/api/index.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import axios, { AxiosInstance, Method, AxiosResponse, AxiosRequestConfig } from 'axios';
|
||||
import Sys from './system';
|
||||
import Member from './member';
|
||||
import Group from './group';
|
||||
|
||||
|
||||
type FieldError = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export default class PKAPI {
|
||||
|
||||
ROUTES = {
|
||||
GET_SYSTEM: (sid?: string) => sid ? `/systems/${sid}` : `/systems/@me`,
|
||||
GET_MEMBER_LIST: (sid?: string) => sid ? `/systems/${sid}/members` : `/systems/@me/members`,
|
||||
GET_MEMBER: (mid: string) => `/members/${mid}`,
|
||||
GET_GROUP_LIST: (sid?: string) => sid ? `/systems/${sid}/groups` : `/systems/@me/groups`,
|
||||
|
||||
PATCH_SYSTEM: () => `/systems/@me`,
|
||||
|
||||
POST_MEMBER: () => `/members`
|
||||
}
|
||||
|
||||
baseUrl: string;
|
||||
instance: AxiosInstance
|
||||
|
||||
constructor(baseUrl?: string) {
|
||||
this.baseUrl = baseUrl || 'https://api.pluralkit.me';
|
||||
|
||||
this.instance = axios.create({
|
||||
baseURL: this.baseUrl + '/v2'
|
||||
})
|
||||
}
|
||||
|
||||
async getSystem(options: { token?: string, id?: any}) {
|
||||
if (!options.token && !options.id) {
|
||||
throw new Error("Must pass a token or id.")
|
||||
}
|
||||
var system: Sys;
|
||||
var res: AxiosResponse;
|
||||
try {
|
||||
res = await this.handle(this.ROUTES.GET_SYSTEM(options.id ? options.id : ""), 'GET', {token: !options.id ? options.token : ""});
|
||||
if (res.status === 200) system = new Sys(res.data);
|
||||
else this.handleErrors(res);
|
||||
} catch (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
return system;
|
||||
}
|
||||
|
||||
async patchSystem(options: {token: string, data: any}) {
|
||||
var body = new Sys(options.data);
|
||||
var system: Sys;
|
||||
var res: AxiosResponse;
|
||||
try {
|
||||
res = await this.handle(this.ROUTES.PATCH_SYSTEM(), 'PATCH', {token: options.token, body: body});
|
||||
if (res.status === 200) system = new Sys(res.data);
|
||||
else this.handleErrors(res);
|
||||
} catch (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
return system;
|
||||
}
|
||||
|
||||
async getMemberList(options: { token?: string, id?: any}) {
|
||||
if (!options.token && !options.id) {
|
||||
throw new Error("Must pass a token or id.")
|
||||
}
|
||||
var members: Member[] = [];
|
||||
var res: AxiosResponse;
|
||||
try {
|
||||
res = await this.handle(this.ROUTES.GET_MEMBER_LIST(options.id ? options.id : ""), 'GET', {token: !options.id ? options.token : ""});
|
||||
if (res.status === 200) {
|
||||
let resObject: any = res.data;
|
||||
resObject.forEach(m => {
|
||||
let member = new Member(m);
|
||||
members.push(member);
|
||||
})
|
||||
}
|
||||
else this.handleErrors(res);
|
||||
} catch (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
async getMember(options: {id: any}) {
|
||||
if (!options.id) {
|
||||
throw new Error("Must pass an id.")
|
||||
}
|
||||
var member: Member;
|
||||
var res: AxiosResponse;
|
||||
try {
|
||||
res = await this.handle(this.ROUTES.GET_MEMBER(options.id), 'GET', {});
|
||||
if (res.status === 200) member = new Member(res.data);
|
||||
else this.handleErrors(res);
|
||||
} catch (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
return member;
|
||||
}
|
||||
|
||||
async postMember(options: {token: any, data: any}) {
|
||||
if (!options.token) throw new Error("Must pass a token.");
|
||||
var body = new Member(options.data);
|
||||
var member: Member;
|
||||
var res: AxiosResponse;
|
||||
try {
|
||||
res = await this.handle(this.ROUTES.POST_MEMBER(), 'POST', {token: options.token, body: body});
|
||||
if (res.status === 200) member = new Member(res.data);
|
||||
else this.handleErrors(res);
|
||||
} catch (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
return member;
|
||||
}
|
||||
|
||||
async getGroupList(options: {token?: string, id?: any}) {
|
||||
if (!options.token && !options.id) {
|
||||
throw new Error("Must pass a token or id.");
|
||||
}
|
||||
var groups: Group[] = [];
|
||||
var res: AxiosResponse;
|
||||
try {
|
||||
res = await this.handle(this.ROUTES.GET_GROUP_LIST(options.id ? options.id : ""), 'GET', {token: !options.id ? options.token : ""});
|
||||
if (res.status === 200) {
|
||||
let resObject: any = res.data;
|
||||
resObject.forEach(g => {
|
||||
let group = new Group(g);
|
||||
groups.push(group);
|
||||
})
|
||||
}
|
||||
else this.handleErrors(res);
|
||||
} catch (error) {
|
||||
throw new Error(error.message);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
handleErrors(res: any) {
|
||||
if (res.status === 500) throw new Error("500: Internal server error.");
|
||||
else if (res.status === 401) throw new Error("401: Your token is invalid.");
|
||||
else {
|
||||
let errorObject: any = res.data
|
||||
if (errorObject.code) {
|
||||
if (errorObject.code === 40001) {
|
||||
var message: string;
|
||||
for (var key in errorObject.errors) {
|
||||
var val = errorObject.errors[key];
|
||||
}
|
||||
} else {
|
||||
throw new Error(errorObject.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async handle(url: string, method: Method, options: {token?: string, body?: object}) {
|
||||
var headers = {}
|
||||
var request: AxiosRequestConfig = {url, method, headers}
|
||||
|
||||
if(options.token) request.headers["Authorization"] = options.token;
|
||||
if (options.body) {
|
||||
request.headers["Content-Type"] = "application/json";
|
||||
request.data = JSON.stringify(options.body);
|
||||
}
|
||||
|
||||
try {
|
||||
var res = await this.instance(request);
|
||||
} catch (error) {
|
||||
res = error.response;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
55
src/api/member.ts
Normal file
55
src/api/member.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
interface MemberPrivacy {
|
||||
visibility?: string | boolean | null,
|
||||
description_privacy?: string | boolean | null,
|
||||
name_privacy?: string | boolean | null,
|
||||
birthday_privacy?: string | boolean | null,
|
||||
pronoun_privacy?: string | boolean | null,
|
||||
avatar_privacy?: string | boolean | null,
|
||||
metadata_privacy?: string | boolean | null
|
||||
}
|
||||
|
||||
export default class Member {
|
||||
id?: string;
|
||||
uuid?: string;
|
||||
name?: string;
|
||||
display_name?: string;
|
||||
color?: string;
|
||||
birthday?: string;
|
||||
pronouns?: string;
|
||||
avatar_url?: string;
|
||||
banner?: string;
|
||||
description?: string;
|
||||
created?: string;
|
||||
keep_proxy?: boolean
|
||||
system?: string;
|
||||
proxy_tags?: Array<object>;
|
||||
privacy?: MemberPrivacy
|
||||
|
||||
constructor(data: any) {
|
||||
this.id = data.id;
|
||||
this.uuid = data.uuid;
|
||||
this.name = data.name;
|
||||
this.display_name = data.display_name;
|
||||
this.color = data.color;
|
||||
this.birthday = data.birthday;
|
||||
this.pronouns = data.pronouns;
|
||||
this.avatar_url = data.avatar_url;
|
||||
this.banner = data.banner;
|
||||
this.description = data.description;
|
||||
this.created = data.created;
|
||||
this.system = data.system;
|
||||
this.proxy_tags = data.proxy_tags;
|
||||
this.keep_proxy = data.keep_proxy;
|
||||
if (data.privacy) {
|
||||
this.privacy = {
|
||||
visibility: data.privacy.visibility,
|
||||
description_privacy: data.privacy.description_privacy,
|
||||
name_privacy: data.privacy.name_privacy,
|
||||
birthday_privacy: data.privacy.birthday_privacy,
|
||||
pronoun_privacy: data.privacy.pronouns_privacy,
|
||||
avatar_privacy: data.privacy.avatar_privacy,
|
||||
metadata_privacy: data.privacy.metadata_privacy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
src/api/system.ts
Normal file
43
src/api/system.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
interface SystemPrivacy {
|
||||
description_privacy?: string,
|
||||
member_list_privacy?: string,
|
||||
front_privacy?: string,
|
||||
front_history_privacy?: string,
|
||||
group_list_privacy?: string
|
||||
}
|
||||
|
||||
export default class Sys {
|
||||
id?: string;
|
||||
uuid?: string;
|
||||
name?: string;
|
||||
description?: string;
|
||||
tag?: string;
|
||||
avatar_url?: string;
|
||||
banner?: string;
|
||||
timezone?: string;
|
||||
created?: string;
|
||||
privacy?: SystemPrivacy;
|
||||
color?: string;
|
||||
|
||||
constructor(data: any) {
|
||||
this.id = data.id;
|
||||
this.uuid = data.uuid;
|
||||
this.name = data.name;
|
||||
this.description = data.description;
|
||||
this.tag = data.tag;
|
||||
this.avatar_url = data.avatar_url;
|
||||
this.banner = data.banner;
|
||||
this.timezone = data.timezone;
|
||||
this.created = data.created;
|
||||
this.color = data.color;
|
||||
if (data.privacy) {
|
||||
this.privacy = {
|
||||
description_privacy: data.privacy.description_privacy,
|
||||
member_list_privacy: data.privacy.member_list_privacy,
|
||||
front_privacy: data.privacy.front_privacy,
|
||||
front_history_privacy: data.privacy.front_history_privacy,
|
||||
group_list_privacy: data.privacy.group_list_privacy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
src/lib/Navigation.svelte
Normal file
27
src/lib/Navigation.svelte
Normal file
@@ -0,0 +1,27 @@
|
||||
<script lang="ts">
|
||||
import {Navbar, NavbarBrand, Nav, NavItem, NavLink, Collapse, NavbarToggler} from 'sveltestrap';
|
||||
let isOpen = false;
|
||||
|
||||
const toggle = () => (isOpen = !isOpen);
|
||||
</script>
|
||||
|
||||
<Navbar color="transparent" expand="lg">
|
||||
<NavbarBrand style="color: white;">pk-webs</NavbarBrand>
|
||||
<NavbarToggler on:click={toggle}></NavbarToggler>
|
||||
<Collapse {isOpen} navbar>
|
||||
<Nav class="ms-auto" navbar>
|
||||
<NavItem>
|
||||
<NavLink href="/dash">Dash</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/settings">Settings</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/templates">templates</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="/public">Public</NavLink>
|
||||
</NavItem>
|
||||
</Nav>
|
||||
</Collapse>
|
||||
</Navbar>
|
7
src/main.ts
Normal file
7
src/main.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import App from './App.svelte'
|
||||
|
||||
const app = new App({
|
||||
target: document.getElementById('app')
|
||||
})
|
||||
|
||||
export default app
|
2
src/vite-env.d.ts
vendored
Normal file
2
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="svelte" />
|
||||
/// <reference types="vite/client" />
|
Reference in New Issue
Block a user