forked from NotNet/gluestick
add back hold-to-unlink
This commit is contained in:
parent
3e24c99db4
commit
1340bf531a
|
@ -58,29 +58,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the !importants here piss me off but it wouldn't accept the property otherwise */
|
|
||||||
.progress {
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
var(--fg-darker) 50%,
|
|
||||||
var(--bg-dark) 50%
|
|
||||||
) !important;
|
|
||||||
background-size: 200% 100% !important;
|
|
||||||
background-position: right bottom !important;
|
|
||||||
transition: all 0s linear !important;
|
|
||||||
|
|
||||||
border: 0;
|
|
||||||
border-radius: 0.15rem;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* when clicked */
|
|
||||||
.progress:active {
|
|
||||||
transition: all 3s linear !important;
|
|
||||||
background-position: left bottom !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.multiButtons {
|
.multiButtons {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { UserInfo } from "@/ldap";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import styles from "./AboutMe.module.css";
|
import styles from "./AboutMe.module.css";
|
||||||
import AvatarChanger from "@/components/AvatarChanger";
|
import AvatarChanger from "@/components/AvatarChanger";
|
||||||
import Input, { Label } from "@/components/Input";
|
import Input, { Hint, Label } from "@/components/Input";
|
||||||
import { Form, Formik, FormikHelpers } from "formik";
|
import { Form, Formik, FormikHelpers } from "formik";
|
||||||
import {
|
import {
|
||||||
AboutMeFormValues,
|
AboutMeFormValues,
|
||||||
|
@ -204,6 +204,8 @@ export default function AboutMe({
|
||||||
|
|
||||||
<div className={styles.connections}>
|
<div className={styles.connections}>
|
||||||
<Label>Connections</Label>
|
<Label>Connections</Label>
|
||||||
|
<Hint>Click to link, hold to unlink.</Hint>
|
||||||
|
|
||||||
<Connection
|
<Connection
|
||||||
service="Discord"
|
service="Discord"
|
||||||
authState={discordState}
|
authState={discordState}
|
||||||
|
|
|
@ -55,3 +55,21 @@
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the !importants here piss me off but it wouldn't accept the property otherwise */
|
||||||
|
.progress {
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
var(--fg-darker) 50%,
|
||||||
|
var(--bg-dark) 50%
|
||||||
|
) !important;
|
||||||
|
background-size: 200% 100% !important;
|
||||||
|
background-position: right bottom !important;
|
||||||
|
transition: all 0s linear !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* when clicked */
|
||||||
|
.progress:active {
|
||||||
|
transition: all 3s linear !important;
|
||||||
|
background-position: left bottom !important;
|
||||||
|
}
|
||||||
|
|
|
@ -18,39 +18,41 @@ export default function Connection({
|
||||||
icon?: () => JSX.Element;
|
icon?: () => JSX.Element;
|
||||||
}) {
|
}) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [changing, setChanging] = React.useState(false);
|
|
||||||
|
|
||||||
// TODO: Reimplement hold-to-unlink.
|
const holdTime = authState?.connected ? 3000 : 0;
|
||||||
|
const interval = React.useRef<NodeJS.Timeout | null>();
|
||||||
|
|
||||||
async function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
|
const execute = async () => {
|
||||||
event.preventDefault();
|
const name = authState?.name.toLowerCase();
|
||||||
|
if (!authState?.connected) {
|
||||||
if (unavailable) return;
|
router.push(`/oauth/${name}/login`);
|
||||||
|
|
||||||
const provider = service.toLowerCase();
|
|
||||||
if (authState?.connected === false) {
|
|
||||||
setChanging(true);
|
|
||||||
router.push(`/oauth/${provider}/login`);
|
|
||||||
} else {
|
} else {
|
||||||
setChanging(true);
|
await fetch(`/api/unlink?provider=${name}`, { method: "POST" });
|
||||||
if (confirm(`Unlink your ${service} account?`)) {
|
router.refresh();
|
||||||
await fetch(`/api/unlink?provider=${provider}`, { method: "POST" });
|
|
||||||
window.location.reload();
|
|
||||||
} else {
|
|
||||||
setChanging(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const mouseDown = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
interval.current = setTimeout(execute, holdTime);
|
||||||
|
};
|
||||||
|
|
||||||
|
const mouseUp = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (interval.current) clearTimeout(interval.current);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
className={classnames(
|
className={classnames(
|
||||||
styles.connection,
|
styles.connection,
|
||||||
unavailable ? styles.unavailable : null,
|
unavailable ? styles.unavailable : null,
|
||||||
!authState?.connected ? styles.disconnected : null
|
!authState?.connected ? styles.disconnected : styles.progress
|
||||||
)}
|
)}
|
||||||
onClick={handleClick}
|
disabled={unavailable}
|
||||||
disabled={changing}
|
onMouseDown={mouseDown}
|
||||||
|
onMouseUp={mouseUp}
|
||||||
>
|
>
|
||||||
<div className={styles.iconContainer}>
|
<div className={styles.iconContainer}>
|
||||||
{icon ? icon() : <span className={styles.dot}></span>}
|
{icon ? icon() : <span className={styles.dot}></span>}
|
||||||
|
|
|
@ -23,6 +23,17 @@ export function Label({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function Hint({
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: LabelHTMLAttributes<HTMLLabelElement>) {
|
||||||
|
return (
|
||||||
|
<label className={classnames(styles.hint, props.className)} {...props}>
|
||||||
|
{children}
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function Input<T>(
|
export default function Input<T>(
|
||||||
props: CustomInputProps<T> &
|
props: CustomInputProps<T> &
|
||||||
FieldAttributes<{ hint?: string; label?: string; disabled?: boolean }>
|
FieldAttributes<{ hint?: string; label?: string; disabled?: boolean }>
|
||||||
|
|
Loading…
Reference in New Issue