Skip to content

Commit

Permalink
✨ feat: draggable sdk button (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustin01 authored Aug 6, 2024
1 parent f974b6b commit 037c31b
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 21 deletions.
78 changes: 59 additions & 19 deletions packages/sdk/src/lib/dom/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
import { CONTROLLER_CONTAINER_ID, IFRAME_CONTAINER_ID } from "../constants"
import { HibitEnv, HibitIdPage } from "../types"
import { getHibitIdUrl } from "../utils"
import { clamp, getHibitIdUrl } from "../utils"
import './index.css'

export class HibitIdController {
private container: HTMLDivElement
private button: HTMLButtonElement
private open = false
private dragging = false
private mouseDownStartAt = 0
private onClick: () => void
private onMove: (x: number, y: number) => void

constructor(onClick: () => void, onMove: (x: number, y: number) => void) {
this.onClick = onClick
this.onMove = onMove

constructor(onClick: () => void) {
const existed = document.getElementById(CONTROLLER_CONTAINER_ID)
existed?.remove()
const container = document.createElement('div')
container.id = CONTROLLER_CONTAINER_ID
const button = document.createElement('button')
button.classList.add('hidden')
button.onclick = this.getClickHandler(onClick)
button.onmousedown = this.handleMouseDown
window.addEventListener('mouseup', this.handleMouseUp)
window.addEventListener('mousemove', this.handleMouseMove)
container.appendChild(button)
document.body.appendChild(container)

Expand All @@ -40,12 +49,35 @@ export class HibitIdController {

public destroy = () => {
this.container?.remove()
window.removeEventListener('mouseup', this.handleMouseUp)
window.removeEventListener('mousemove', this.handleMouseMove)
}

private handleClick = () => {
this.onClick?.()
this.setOpen(!this.open)
}

private getClickHandler = (onClick: () => void) => {
return () => {
onClick()
this.setOpen(!this.open)
private handleMouseDown = () => {
this.dragging = true
this.mouseDownStartAt = Date.now()
}

private handleMouseUp = () => {
this.dragging = false
if (Date.now() - this.mouseDownStartAt < 200) {
this.handleClick()
}
}

private handleMouseMove = (e: MouseEvent) => {
if (this.dragging) {
const rect = this.getBoundingRect()
const right = clamp(0, window.innerWidth - rect.right - e.movementX, window.innerWidth - rect.width)
const bottom = clamp(0, window.innerHeight - rect.bottom - e.movementY, window.innerHeight - rect.height)
this.container.style.right = `${right}px`
this.container.style.bottom = `${bottom}px`
this.onMove(e.clientX, e.clientY)
}
}
}
Expand Down Expand Up @@ -78,24 +110,32 @@ export class HibitIdIframe {
return this._visible
}

public updateStyle = (style: Record<string, string>) => {
Object.keys(style).forEach((key) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
this.container.style[key] = style[key]
})
}

public show = (options: {
fullscreen: boolean,
style: Record<string, string>
}) => {
if (options.fullscreen) {
this.container.style.top = '0'
this.container.style.left = '0'
this.container.style.width = '100%'
this.container.style.height = '100%'
this.container.style.bottom = 'unset'
this.container.style.right = 'unset'
this.updateStyle({
top: '0',
left: '0',
width: '100%',
height: '100%',
bottom: 'unset',
right: 'unset',
})
} else {
this.container.style.top = 'unset'
this.container.style.left = 'unset'
Object.keys(options.style).forEach((key) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
this.container.style[key] = options.style[key]
this.updateStyle({
top: 'unset',
left: 'unset',
...options.style
})
}
this._visible = true
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ export const getHibitIdUrl = (env: HibitEnv, initialPage: HibitIdPage) => {
url = `${url}/${initialPage === 'login' ? 'login' : ''}`
return url
}

export const clamp = (value: number, min: number, max: number) => {
return Math.min(Math.max(value, min), max)
}
20 changes: 18 additions & 2 deletions packages/sdk/src/lib/wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { RPC_SERVICE_NAME } from './constants';
import { HibitIdController, HibitIdIframe } from './dom';
import { AccountsChangedRequest, BridgePromise, ChainChangedRequest, ChainInfo, ConnectResponse, GetBalanceRequest, GetBalanceResponse, HibitEnv, HibitIdEventHandlerMap, HibitIdPage, LoginChangedRequest, SignMessageResponse, TransferRequest, TransferResponse, WalletAccount } from './types';
import { ClientExposeRPCMethod, HibitIdChainId, HibitIdExposeRPCMethod } from './enums';
import { clamp } from './utils';

const LOGIN_SESSION_KEY = 'hibit-id-session'

Expand Down Expand Up @@ -31,7 +32,7 @@ export class HibitIdWallet {
}
this.prepareIframe().then(() => {
if (this._hasSession) {
this._controller = new HibitIdController(this.toggleIframe)
this._controller = new HibitIdController(this.toggleIframe, this.handleControllerMove)
}
})
}
Expand Down Expand Up @@ -208,6 +209,21 @@ export class HibitIdWallet {
this._rpc = rpc
}

private handleControllerMove = (x: number, y: number) => {
if (!this._iframe) return
const controllerRect = this._controller?.getBoundingRect()
const maxRight = window.innerWidth - (controllerRect?.width ?? 0)
const maxBottom = window.innerHeight - (controllerRect?.height ?? 0)
const right = clamp(0, controllerRect ? (window.innerWidth - controllerRect.right) : 50, maxRight)
const bottom = clamp(0, controllerRect ? (window.innerHeight - controllerRect.top + 20) : 50, maxBottom)
this._iframe.updateStyle({
// width: '332px',
// height: '502px',
right: `${right}px`,
bottom: `${bottom}px`
})
}

private showIframe = (fullscreen?: boolean) => {
if (!this._iframe) return
if (fullscreen) {
Expand Down Expand Up @@ -240,7 +256,7 @@ export class HibitIdWallet {
this.showIframe(true)
} else {
if (!this._controller) {
this._controller = new HibitIdController(this.toggleIframe)
this._controller = new HibitIdController(this.toggleIframe, this.handleControllerMove)
}
if (this._hasSession) {
return
Expand Down

0 comments on commit 037c31b

Please sign in to comment.