Skip to content

Commit

Permalink
feat: Right Hand Cursor Implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
ful1e5 committed Jan 10, 2024
1 parent 2a13d3f commit b614463
Show file tree
Hide file tree
Showing 21 changed files with 252 additions and 84 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### What's New?

- Right Hand Cursor Mode added
- Download as PNGs Option added
- Interactive Cursor size component
- More polished UI
Expand Down
77 changes: 77 additions & 0 deletions core/builder/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,83 @@ def _assign(v) -> int:
self.links = links


rconfigs: Dict[str, Config] = {
"left_ptr": Config(
x=207,
y=24,
winname="Pointer",
xname="left_ptr",
links=["arrow", "default", "top_left_arrow"],
),
"left_ptr_watch": Config(
x=197,
y=24,
winname="Work",
xname="left_ptr_watch",
links=[
"00000000000000020006000e7e9ffc3f",
"08e8e1c95fe2fc01f976f1e063a24ccd",
"3ecb610c1bf2410f44200f48c40d3599",
"progress",
],
),
"right_ptr": Config(
x=55,
y=17,
winname="Alternate",
xname="right_ptr",
links=["draft_large", "draft_small"],
),
"circle": Config(
x=207,
y=24,
winname="Unavailable",
xname="circle",
links=["forbidden"],
),
"context-menu": Config(
x=207,
y=24,
xname="context-menu",
),
"copy": Config(
x=207,
y=24,
xname="copy",
links=[
"1081e37283d90000800003c07f3ef6bf",
"6407b0e94181790501fd1e167b474872",
"b66166c04f8c3109214a4fbd64a50fc8",
],
),
"link": Config(
x=207,
y=24,
xname="link",
links=[
"3085a0e285430894940527032f8b26df",
"640fb0e74195791501fd1ed57b41487f",
"a2a266d0498c3104214a47bd64ab0fc8",
],
),
"pointer-move": Config(
x=207,
y=24,
xname="pointer-move",
),
"person": Config(
x=207,
y=24,
winname="Person",
),
"pin": Config(
x=207,
y=24,
winname="Pin",
),
}


configs: Dict[str, Config] = {
"bd_double_arrow": Config(
winname="Dgn1",
Expand Down
5 changes: 4 additions & 1 deletion core/builder/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from clickgen.writer import to_win, to_x11
from PIL import Image

from core.builder.config import configs, gsubtmp
from core.builder.config import configs, gsubtmp, rconfigs
from core.utils.parser import UploadFormData


Expand All @@ -18,6 +18,7 @@ def store_cursors(sid: str, data: UploadFormData, logger: Logger):
platform = data.platform
pngs = data.frames
size = data.size
right_mode = data.mode == "right"
delay = data.delay

try:
Expand All @@ -26,6 +27,8 @@ def store_cursors(sid: str, data: UploadFormData, logger: Logger):
return None, errors

config = configs.get(name, None)
if right_mode:
config = rconfigs.get(name, config)
if not config:
raise ValueError(f"Unable to find Configuration for '{name}'")
else:
Expand Down
12 changes: 12 additions & 0 deletions core/utils/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ class UploadFormData:
platform: str
size: int
delay: int
mode: Literal["left", "right"]
errors: List[str]


def parse_upload_formdata(request: Request, logger: Logger):
errors: List[str] = []

name: str = ""
mode: Literal["left", "right"] = "left"
size: int = 0
delay: int = 0
platform: str = ""
Expand All @@ -32,6 +34,7 @@ def parse_upload_formdata(request: Request, logger: Logger):
raise ValueError("JSON data Not Found at 'data' key in FormData request.")
else:
data = json.loads(form_data)

s = data.get("size", None)
if not s:
raise ValueError("'size' Not Found in JSON 'data' ")
Expand All @@ -58,6 +61,14 @@ def parse_upload_formdata(request: Request, logger: Logger):
else:
platform = p

m = data.get("mode", None)
if m != "left" and m != "right":
raise ValueError(
"Invalid 'mode' type. It must be type 'left' or 'right'"
)
else:
mode = m

n = data.get("name", None)
if not n:
raise ValueError("'name' Not Found in JSON 'data' ")
Expand Down Expand Up @@ -90,6 +101,7 @@ def parse_upload_formdata(request: Request, logger: Logger):
size=size,
delay=delay,
platform=platform,
mode=mode,
errors=errors,
)

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "bibata",
"description": "CLI for converting cursor svg files to png.",
"author": "Abdulkaiz Khatri <[email protected]>",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"bugs": {
"url": "https://github.com/ful1e5/bibata/issues",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- AlterEnum
-- This migration adds more than one value to an enum.
-- With PostgreSQL versions 11 and earlier, this is not possible
-- in a single migration. This can be worked around by creating
-- multiple migrations, each migration adding only one value to
-- the enum.


ALTER TYPE "Type" ADD VALUE 'ModernRight';
ALTER TYPE "Type" ADD VALUE 'OriginalRight';
2 changes: 2 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ enum Platform {

enum Type {
Modern
ModernRight
Original
OriginalRight
}

model User {
Expand Down
11 changes: 7 additions & 4 deletions src/app/(home)/studio/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Image } from 'bibata/app';

export default function StudioPage() {
const [type, setType] = useState(TYPES[0]);
const [cursorMode, setCursorMode] = useState<'left' | 'right'>('left');
const [cursorSize, setCursorSize] = useState(SIZES[3]);

const [colorName, setColorName] = useState('Amber');
Expand Down Expand Up @@ -71,12 +72,13 @@ export default function StudioPage() {
/>
<div className='mt-5'>
<TypePicker
list={TYPES}
list={TYPES.filter((a) => !a.match('Right'))}
value={type}
onClick={(v) => {
if (v !== type) {
onChange={(t, rhm) => {
if (t !== type) {
resetImages();
setType(v);
setType(t);
setCursorMode(rhm ? 'right' : 'left');
refreshToken();
}
}}
Expand Down Expand Up @@ -114,6 +116,7 @@ export default function StudioPage() {
<DownloadButton
auth={token}
version={version}
mode={cursorMode}
disabled={images.length === 0}
lock={imagesCount === 0 || imagesCount !== images.length}
config={{
Expand Down
33 changes: 16 additions & 17 deletions src/app/api/svg/fetch/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,35 @@ export async function GET(request: NextRequest) {
}

const version = request.nextUrl.searchParams.get('v');
const type = request.nextUrl.searchParams.get('type');
const response = await update(type, version);
const response = await update(version);

return NextResponse.json(
{ fetchAt: Date.now(), ...response },
{ status: 200 }
);
}

const update = async (type: string | null, version: string | null) => {
if (!type) {
return { error: `Invalid type: ${type}` };
}
if (!TYPES.includes(type)) {
return { error: `${type} is not available` };
}

const update = async (version: string | null) => {
const fetcher = new FetchSVG();

try {
const redis = new ImageRedis();
const file = await fetcher.getFile();

const svgs = await fetcher.fetchSVGs({ type, version });
if (!svgs) {
return { error: 'Something went wrong. SVGs. not found' };
}
for (const type of TYPES) {
const svgs = await fetcher.fetchSVGs({ file, type, version });
if (!svgs) {
return {
error: 'Something went wrong. SVGs. not found',
type,
version
};
}

const key = `${type}:${version}`;
await redis.del(key);
await redis.saveSVGs(key, svgs);
const key = `${type}:${version}`;
await redis.del(key);
await redis.saveSVGs(key, svgs);
}

return;
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/svg/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export async function GET(request: NextRequest) {
}
} else {
return NextResponse.json(
{ error: `No images found for '${type}'` },
{ error: `No cursor bitmaps found for '${type}'` },
{ status: 404 }
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/DownloadButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Props = {
lock?: boolean;
auth: AuthToken;
version: string;
mode: 'left' | 'right';
config: {
type: string;
color: Color;
Expand Down Expand Up @@ -86,6 +87,7 @@ export const DownloadButton: React.FC<Props> = (props) => {
name: i.name,
frames: i.frames,
delay: i.delay,
mode: props.mode,
...options
})
);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ export const Footer: React.FC<Props> = (_props) => {
rel='noopener noreferrer'>
<TwitchLogo size={15} />
</Link>
<span className='relative flex h-2 w-2 sm:h-3 sm:w-3 -translate-y-1 -translate-x-1 sm:-translate-x-2'>
<span className='animate-ping absolute inline-flex h-full w-full rounded-full bg-sky-400 opacity-75'></span>
<span className='relative flex h-1.5 w-1.5 sm:h-3 sm:w-3 -translate-y-1 -translate-x-0.5 sm:-translate-x-2'>
<span className='animate-ping absolute inline-flex h-full w-full rounded-full bg-purple-500 opacity-75'></span>
<span className='relative inline-flex rounded-full h-2 w-2 sm:h-3 sm:w-3 bg-purple-500'></span>
</span>
</li>
Expand Down Expand Up @@ -163,7 +163,7 @@ export const Footer: React.FC<Props> = (_props) => {
</div>
<div className='mt-5'>
<p className='text-white/[.6] font-bold'>
Copyright © 2023-{currentYear} AbdulKaiz Khatri
Copyright © {currentYear} AbdulKaiz Khatri
</p>
</div>
</div>
Expand Down
38 changes: 18 additions & 20 deletions src/components/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,24 @@ type Props = {
export const Message: React.FC<Props> = (props) => {
return (
<div className='text-center py-4 lg:px-4'>
<div className='transition hover:scale-105 active:scale-95'>
<Link className='' href={props.href}>
<div
className='p-2 bg-indigo-800 items-center text-indigo-100 leading-none rounded-full flex sm:inline-flex'
role='alert'>
<span className='flex rounded-full bg-indigo-500 uppercase px-2 py-1 text-xs font-bold mr-3'>
{props.tag}
</span>
<span className='font-semibold text-xs mr-2 text-left flex-auto'>
{props.message}
</span>
<svg
className='fill-current opacity-75 h-4 w-4'
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 20 20'>
<path d='M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z' />
</svg>
</div>
</Link>
</div>
<Link href={props.href}>
<div
className='transition hover:scale-105 active:scale-95 p-2 bg-indigo-800 items-center text-indigo-100 leading-none rounded-full flex sm:inline-flex'
role='alert'>
<span className='flex rounded-full bg-indigo-500 uppercase px-2 py-1 text-xs font-bold mr-3'>
{props.tag}
</span>
<span className='font-semibold text-xs mr-2 text-left flex-auto'>
{props.message}
</span>
<svg
className='fill-current opacity-75 h-4 w-4'
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 20 20'>
<path d='M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z' />
</svg>
</div>
</Link>
</div>
);
};
Loading

0 comments on commit b614463

Please sign in to comment.