noot
This commit is contained in:
parent
bd20e23b15
commit
f00708e80d
@ -1,4 +1,5 @@
|
||||
dist
|
||||
dist/**
|
||||
**/vendor/**
|
||||
**/locales/**
|
||||
generated.*
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
|
||||
"files": {
|
||||
"ignoreUnknown": true
|
||||
"ignoreUnknown": true,
|
||||
"includes": ["src/**/*.{ts,tsx,js,jsx}"]
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
|
||||
@ -48,7 +48,8 @@ export const CharacterCard = ({ character }: { character: TricksterCharacter })
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setSelectedCharacter(character)
|
||||
}}
|
||||
@ -64,7 +65,11 @@ export const CharacterCard = ({ character }: { character: TricksterCharacter })
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-row justify-center">
|
||||
{character.base_job === -8 ? (
|
||||
<img className="h-8" src="https://beta.lifeto.co/item_img/gel.nri.003.000.png" />
|
||||
<img
|
||||
className="h-8"
|
||||
src="https://beta.lifeto.co/item_img/gel.nri.003.000.png"
|
||||
alt="Gel character"
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
className="h-16"
|
||||
@ -75,6 +80,7 @@ export const CharacterCard = ({ character }: { character: TricksterCharacter })
|
||||
)
|
||||
.toString()
|
||||
.padStart(3, '0')}_13.png`}
|
||||
alt={`Character ${character.name}`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@ -94,7 +100,7 @@ export const CharacterCard = ({ character }: { character: TricksterCharacter })
|
||||
</FloatingPortal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -157,7 +163,7 @@ export const CharacterRoulette = () => {
|
||||
}}
|
||||
></input>
|
||||
<div className="flex flex-row flex-wrap overflow-x-scroll gap-1 h-full min-h-36 max-w-48">
|
||||
{searchResults ? searchResults : <></>}
|
||||
{searchResults ? searchResults : null}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@ -46,7 +46,8 @@ const InventoryTabs = () => {
|
||||
<div className="flex flex-row gap-1">
|
||||
{sections.map(x => {
|
||||
return (
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setInventoryFilterTab(x.value)
|
||||
}}
|
||||
@ -55,14 +56,15 @@ const InventoryTabs = () => {
|
||||
${inventoryFilter.tab === x.value ? selectedStyle : ''}`}
|
||||
>
|
||||
{x.name}
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<div className="flex flex-row gap-1">
|
||||
{cardSections.map(x => {
|
||||
return (
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setInventoryFilterTab(x.value)
|
||||
}}
|
||||
@ -71,7 +73,7 @@ ${inventoryFilter.tab === x.value ? selectedStyle : ''}`}
|
||||
${inventoryFilter.tab === x.value ? selectedStyle : ''}`}
|
||||
>
|
||||
{x.name}
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
@ -103,41 +105,45 @@ export const Inventory = () => {
|
||||
<div className="flex flex-col py-2 flex-0 justify-between h-full">
|
||||
<div className="flex flex-row justify-between">
|
||||
<div className="flex flex-row gap-2">
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
className="whitespace-pre bg-blue-200 px-2 py-1 rounded-xl hover:cursor-pointer hover:bg-blue-300"
|
||||
onClick={() => {
|
||||
addPageItemSelection()
|
||||
}}
|
||||
>
|
||||
select filtered
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="whitespace-pre bg-blue-200 px-2 py-1 rounded-xl hover:cursor-pointer hover:bg-blue-300"
|
||||
onClick={() => {
|
||||
addFilterItemSelection()
|
||||
}}
|
||||
>
|
||||
select page
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="whitespace-pre bg-blue-200 px-2 py-1 rounded-xl hover:cursor-pointer hover:bg-blue-300"
|
||||
onClick={() => {
|
||||
clearItemSelection()
|
||||
}}
|
||||
>
|
||||
clear{' '}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-row">
|
||||
<InventoryTargetSelector />
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
onClick={_e => {
|
||||
// sendOrders()
|
||||
}}
|
||||
className="hover:cursor-pointer whitespace-preborder border-black-1 bg-orange-200 hover:bg-orange-300 px-2 py-1"
|
||||
>
|
||||
Move Selected
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -152,22 +158,26 @@ export const Inventory = () => {
|
||||
setSearch(e.target.value)
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
className="hover:cursor-pointer border border-black-1 bg-green-200 hover:bg-green-300 px-2 py-1 h-full flex items-center"
|
||||
onClick={() => {
|
||||
paginateInventory(-1)
|
||||
}}
|
||||
aria-label="Previous page"
|
||||
>
|
||||
<FaArrowLeft />
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="hover:cursor-pointer border border-black-1 bg-green-200 hover:bg-green-300 px-2 py-1 h-full flex items-center"
|
||||
onClick={() => {
|
||||
paginateInventory(1)
|
||||
}}
|
||||
aria-label="Next page"
|
||||
>
|
||||
<FaArrowRight />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -28,9 +28,11 @@ const AccountInventorySelectorItem = forwardRef<
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
// biome-ignore lint/a11y/useSemanticElements: Custom autocomplete component needs role="option"
|
||||
role="option"
|
||||
id={id}
|
||||
aria-selected={active}
|
||||
tabIndex={-1}
|
||||
{...rest}
|
||||
style={{
|
||||
background: active ? 'lightblue' : 'none',
|
||||
@ -149,8 +151,8 @@ export const InventoryTargetSelector = () => {
|
||||
>
|
||||
{items.map((item, index) => (
|
||||
<AccountInventorySelectorItem
|
||||
key={item.path}
|
||||
{...getItemProps({
|
||||
key: item.path,
|
||||
ref(node) {
|
||||
listRef.current[index] = node
|
||||
},
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useAtom } from 'jotai'
|
||||
import { useState } from 'react'
|
||||
import useLocalStorage from 'use-local-storage'
|
||||
import { LoginHelper } from '../lib/session'
|
||||
import { login, logout } from '../lib/session'
|
||||
import { loginStatusAtom } from '../state/atoms'
|
||||
|
||||
export const LoginWidget = () => {
|
||||
@ -19,8 +19,9 @@ export const LoginWidget = () => {
|
||||
<div>{loginState.community_name}</div>
|
||||
<div className="flex flex-row gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
LoginHelper.logout().finally(() => {
|
||||
logout().finally(() => {
|
||||
refetchLoginState()
|
||||
})
|
||||
return
|
||||
@ -40,7 +41,7 @@ export const LoginWidget = () => {
|
||||
<div className="flex flex-col">
|
||||
<form
|
||||
action={() => {
|
||||
LoginHelper.login(username, password)
|
||||
login(username, password)
|
||||
.catch(e => {
|
||||
setLoginError(e.message)
|
||||
})
|
||||
@ -58,7 +59,6 @@ export const LoginWidget = () => {
|
||||
setUsername(e.target.value)
|
||||
}}
|
||||
value={username}
|
||||
id="username"
|
||||
placeholder="username"
|
||||
className="w-32 pl-2 pb-1 border-b border-gray-600 placeholder-gray-500"
|
||||
/>
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
import { SessionContextProvider } from './SessionContext'
|
||||
|
||||
interface IContext {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
function AppContext(props: IContext): any {
|
||||
const { children } = props
|
||||
const providers = [SessionContextProvider]
|
||||
const res = providers.reduceRight((acc, CurrVal) => <CurrVal>{acc as any}</CurrVal>, children)
|
||||
return res as any
|
||||
}
|
||||
|
||||
export default AppContext
|
||||
@ -1,80 +0,0 @@
|
||||
import { createContext, useContext, useState } from 'react'
|
||||
|
||||
type Setter<T> = React.Dispatch<React.SetStateAction<T | undefined>>
|
||||
type MustSetter<T> = React.Dispatch<React.SetStateAction<T>>
|
||||
|
||||
import useLocalStorage from 'use-local-storage'
|
||||
import { BasicColumns, ColumnInfo, ColumnName, DetailsColumns, MoveColumns } from '../lib/columns'
|
||||
import { OrderTracker } from '../lib/lifeto/order_manager'
|
||||
import { StoreColSet } from '../lib/storage'
|
||||
import { ColumnSet } from '../lib/table'
|
||||
|
||||
interface SessionContextProps {
|
||||
orders: OrderTracker
|
||||
activeTable: string
|
||||
screen: string
|
||||
columns: ColumnSet
|
||||
tags: ColumnSet
|
||||
dirty: number
|
||||
currentSearch: string
|
||||
|
||||
setActiveTable: Setter<string>
|
||||
setScreen: Setter<string>
|
||||
setDirty: MustSetter<number>
|
||||
setCurrentSearch: MustSetter<string>
|
||||
}
|
||||
|
||||
const _defaultColumn: (ColumnInfo | ColumnName)[] = [
|
||||
...BasicColumns,
|
||||
...MoveColumns,
|
||||
...DetailsColumns,
|
||||
]
|
||||
|
||||
const SessionContext = createContext({} as SessionContextProps)
|
||||
|
||||
const dotry = (x: any, d: any) => {
|
||||
try {
|
||||
return x()
|
||||
} catch {
|
||||
return d
|
||||
}
|
||||
}
|
||||
|
||||
export const SessionContextProvider = ({ children }: { children: any }) => {
|
||||
const [activeTable, setActiveTable] = useLocalStorage<string>('activeTable', '')
|
||||
const [screen, setScreen] = useLocalStorage<string>('screen', '')
|
||||
const [columns] = useState<ColumnSet>(new ColumnSet(_defaultColumn))
|
||||
const [tags] = useState<ColumnSet>(dotry(() => StoreColSet.Revive('tags'), new ColumnSet()))
|
||||
|
||||
const [orders] = useState<OrderTracker>(new OrderTracker())
|
||||
const [dirty, setDirty] = useState<number>(0)
|
||||
const [currentSearch, setCurrentSearch] = useState<string>('')
|
||||
return (
|
||||
<SessionContext.Provider
|
||||
value={{
|
||||
orders,
|
||||
activeTable,
|
||||
screen,
|
||||
columns,
|
||||
tags,
|
||||
dirty,
|
||||
currentSearch,
|
||||
setActiveTable,
|
||||
setScreen,
|
||||
setDirty,
|
||||
setCurrentSearch,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</SessionContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useSessionContext = (): SessionContextProps => {
|
||||
const context = useContext<SessionContextProps>(SessionContext)
|
||||
if (context === null) {
|
||||
throw new Error('"useSessionContext" should be used inside a "SessionContextProvider"')
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import { App } from './App'
|
||||
import AppContext from './context/AppContext'
|
||||
|
||||
import './lib/superjson'
|
||||
import './index.css'
|
||||
@ -14,9 +13,7 @@ ReactDOM.createRoot(document.getElementById('app') as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<Provider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AppContext>
|
||||
<App />
|
||||
</AppContext>
|
||||
<App />
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
</React.StrictMode>,
|
||||
|
||||
@ -88,15 +88,6 @@ class Count implements ColumnInfo {
|
||||
}
|
||||
|
||||
const spacer = '-----------'
|
||||
class Move implements ColumnInfo {
|
||||
name: ColumnName = 'Move'
|
||||
displayName = 'Target'
|
||||
writable = true
|
||||
options = getMoveTargets
|
||||
getter(_item: TricksterItem): string | number {
|
||||
return spacer
|
||||
}
|
||||
}
|
||||
|
||||
const getMoveTargets = (invs: string[]): string[] => {
|
||||
const out: string[] = []
|
||||
@ -110,6 +101,16 @@ const getMoveTargets = (invs: string[]): string[] => {
|
||||
return out
|
||||
}
|
||||
|
||||
class Move implements ColumnInfo {
|
||||
name: ColumnName = 'Move'
|
||||
displayName = 'Target'
|
||||
writable = true
|
||||
options = getMoveTargets
|
||||
getter(_item: TricksterItem): string | number {
|
||||
return spacer
|
||||
}
|
||||
}
|
||||
|
||||
class MoveCount implements ColumnInfo {
|
||||
name: ColumnName = 'MoveCount'
|
||||
displayName = 'Move #'
|
||||
|
||||
@ -34,9 +34,12 @@ export class LTOApiv0 implements LTOApi {
|
||||
case 'buy-from-order':
|
||||
case 'cancel-order':
|
||||
endpoint = market_endpoint
|
||||
break
|
||||
case 'sell-item':
|
||||
VERB = 'POSTFORM'
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
return this.s.request(VERB as any, e, t, endpoint).then(x => {
|
||||
return x.data
|
||||
|
||||
@ -166,10 +166,13 @@ export class InternalXfer extends BasicOrder {
|
||||
this.originalResponse = x
|
||||
this.stage = 1
|
||||
this.mark('SUCCESS')
|
||||
const origin_item = r.invs.value.get(this.details?.origin_path!)?.items[
|
||||
this.details?.item_uid!
|
||||
]!
|
||||
origin_item.item_count = origin_item.item_count - this.details?.count!
|
||||
if (this.details?.origin_path && this.details?.item_uid && this.details?.count) {
|
||||
const inventory = r.invs.value.get(this.details.origin_path)
|
||||
const origin_item = inventory?.items[this.details.item_uid]
|
||||
if (origin_item) {
|
||||
origin_item.item_count = origin_item.item_count - this.details.count
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw x.message
|
||||
}
|
||||
@ -223,10 +226,13 @@ export class BankItem extends BasicOrder {
|
||||
this.stage = 1
|
||||
this.originalResponse = x
|
||||
this.mark('SUCCESS')
|
||||
const origin_item = r.invs.value.get(this.details?.origin_path!)?.items[
|
||||
this.details?.item_uid!
|
||||
]!
|
||||
origin_item.item_count = origin_item.item_count - this.details?.count!
|
||||
if (this.details?.origin_path && this.details?.item_uid && this.details?.count) {
|
||||
const inventory = r.invs.value.get(this.details.origin_path)
|
||||
const origin_item = inventory?.items[this.details.item_uid]
|
||||
if (origin_item) {
|
||||
origin_item.item_count = origin_item.item_count - this.details.count
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw x.message ? x.message : 'unknown error'
|
||||
}
|
||||
@ -292,12 +298,13 @@ export class PrivateMarket extends BasicOrder {
|
||||
this.mark('SUCCESS')
|
||||
this.listingId = x.data.listing_id
|
||||
this.listingHash = x.data.hash
|
||||
try {
|
||||
const origin_item = r.invs.value.get(this.details?.origin_path!)?.items[
|
||||
this.details?.item_uid!
|
||||
]!
|
||||
origin_item.item_count = origin_item.item_count - this.details?.count!
|
||||
} catch (_e) {}
|
||||
if (this.details?.origin_path && this.details?.item_uid && this.details?.count) {
|
||||
const inventory = r.invs.value.get(this.details.origin_path)
|
||||
const origin_item = inventory?.items[this.details.item_uid]
|
||||
if (origin_item) {
|
||||
origin_item.item_count = origin_item.item_count - this.details.count
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw x.message ? x.message : 'unknown error'
|
||||
}
|
||||
|
||||
@ -65,6 +65,7 @@ export class OrderTracker implements Serializable<OrderTracker> {
|
||||
break
|
||||
case 'MarketMove':
|
||||
newOrder = new MarketMove(o.details).parse(o)
|
||||
break
|
||||
case 'MarketMoveToChar':
|
||||
newOrder = new MarketMoveToChar(o.details).parse(o)
|
||||
break
|
||||
@ -156,8 +157,11 @@ export class OrderSender {
|
||||
}
|
||||
|
||||
private transformInternalOrder(o: OrderDetails): TxnDetails {
|
||||
const origin = this.chars.get(o.origin_path)!
|
||||
const target = this.chars.get(o.target_path)!
|
||||
const origin = this.chars.get(o.origin_path)
|
||||
const target = this.chars.get(o.target_path)
|
||||
if (!origin || !target) {
|
||||
throw new Error(`Character not found: origin=${o.origin_path}, target=${o.target_path}`)
|
||||
}
|
||||
return {
|
||||
origin: origin.id.toString(),
|
||||
target: target.id.toString(),
|
||||
|
||||
@ -26,14 +26,15 @@ export class StatefulLTOApi implements LTOApi {
|
||||
}
|
||||
GetInventory = async (path: string): Promise<TricksterInventory> => {
|
||||
const inv = await this.u.GetInventory(path)
|
||||
if (this.r.invs.value.get(inv.path)) {
|
||||
this.r.invs.value.get(inv.path)!.items = inv.items
|
||||
const existingInv = this.r.invs.value.get(inv.path)
|
||||
if (existingInv) {
|
||||
existingInv.items = inv.items
|
||||
if (inv.galders) {
|
||||
existingInv.galders = inv.galders
|
||||
}
|
||||
} else {
|
||||
this.r.invs.value.set(inv.path, inv)
|
||||
}
|
||||
if (inv.galders) {
|
||||
this.r.invs.value.get(inv.path)!.galders = inv.galders
|
||||
}
|
||||
this.r.dirty.value = this.r.dirty.value + 1
|
||||
return inv
|
||||
}
|
||||
|
||||
@ -150,16 +150,6 @@ class Count implements ColumnInfo {
|
||||
}
|
||||
}
|
||||
|
||||
class Move implements ColumnInfo {
|
||||
name: ColumnName = 'Move'
|
||||
displayName = 'Target'
|
||||
writable = true
|
||||
options = getMoveTargets
|
||||
getter(_item: TricksterItem): string | number {
|
||||
return '---------------------------------------------'
|
||||
}
|
||||
}
|
||||
|
||||
const getMoveTargets = (invs: string[]): string[] => {
|
||||
const out: string[] = []
|
||||
for (const k of invs) {
|
||||
@ -171,6 +161,16 @@ const getMoveTargets = (invs: string[]): string[] => {
|
||||
return out
|
||||
}
|
||||
|
||||
class Move implements ColumnInfo {
|
||||
name: ColumnName = 'Move'
|
||||
displayName = 'Target'
|
||||
writable = true
|
||||
options = getMoveTargets
|
||||
getter(_item: TricksterItem): string | number {
|
||||
return '---------------------------------------------'
|
||||
}
|
||||
}
|
||||
|
||||
class MoveCount implements ColumnInfo {
|
||||
name: ColumnName = 'MoveCount'
|
||||
displayName = 'Move #'
|
||||
|
||||
@ -33,55 +33,62 @@ export interface Session {
|
||||
request: (verb: Method, url: string, data: any, c?: EndpointCreator) => Promise<any>
|
||||
}
|
||||
|
||||
export class LoginHelper {
|
||||
static login = async (user: string, pass: string): Promise<TokenSession> => {
|
||||
return axios
|
||||
.get(login_endpoint('login'), {
|
||||
withCredentials: false,
|
||||
maxRedirects: 0,
|
||||
xsrfCookieName: 'XSRF-TOKEN',
|
||||
})
|
||||
.then(async () => {
|
||||
return axios.post(
|
||||
login_endpoint('login'),
|
||||
{
|
||||
login: user,
|
||||
password: pass,
|
||||
redirectTo: 'lifeto',
|
||||
},
|
||||
{
|
||||
withCredentials: false,
|
||||
maxRedirects: 0,
|
||||
xsrfCookieName: 'XSRF-TOKEN',
|
||||
},
|
||||
)
|
||||
})
|
||||
.then(async () => {
|
||||
return new TokenSession()
|
||||
})
|
||||
.catch(e => {
|
||||
if (e instanceof AxiosError) {
|
||||
if (e.code === 'ERR_BAD_REQUEST') {
|
||||
throw 'invalid username/password'
|
||||
}
|
||||
throw e.message
|
||||
export const login = async (user: string, pass: string): Promise<TokenSession> => {
|
||||
return axios
|
||||
.get(login_endpoint('login'), {
|
||||
withCredentials: false,
|
||||
maxRedirects: 0,
|
||||
xsrfCookieName: 'XSRF-TOKEN',
|
||||
})
|
||||
.then(async () => {
|
||||
return axios.post(
|
||||
login_endpoint('login'),
|
||||
{
|
||||
login: user,
|
||||
password: pass,
|
||||
redirectTo: 'lifeto',
|
||||
},
|
||||
{
|
||||
withCredentials: false,
|
||||
maxRedirects: 0,
|
||||
xsrfCookieName: 'XSRF-TOKEN',
|
||||
},
|
||||
)
|
||||
})
|
||||
.then(async () => {
|
||||
return new TokenSession()
|
||||
})
|
||||
.catch(e => {
|
||||
if (e instanceof AxiosError) {
|
||||
if (e.code === 'ERR_BAD_REQUEST') {
|
||||
throw new Error('invalid username/password')
|
||||
}
|
||||
throw e
|
||||
})
|
||||
}
|
||||
static info = async (): Promise<TricksterAccountInfo> => {
|
||||
return axios
|
||||
.get(raw_endpoint('settings/info'), { withCredentials: false })
|
||||
.then((ans: AxiosResponse) => {
|
||||
return ans.data
|
||||
})
|
||||
}
|
||||
static logout = async (): Promise<void> => {
|
||||
return axios
|
||||
.get(login_endpoint('logout'), { withCredentials: false })
|
||||
.catch(() => {})
|
||||
.then(() => {})
|
||||
}
|
||||
throw new Error(e.message)
|
||||
}
|
||||
throw e
|
||||
})
|
||||
}
|
||||
|
||||
export const getAccountInfo = async (): Promise<TricksterAccountInfo> => {
|
||||
return axios
|
||||
.get(raw_endpoint('settings/info'), { withCredentials: false })
|
||||
.then((ans: AxiosResponse) => {
|
||||
return ans.data
|
||||
})
|
||||
}
|
||||
|
||||
export const logout = async (): Promise<void> => {
|
||||
return axios
|
||||
.get(login_endpoint('logout'), { withCredentials: false })
|
||||
.catch(() => {})
|
||||
.then(() => {})
|
||||
}
|
||||
|
||||
// Keep LoginHelper for backwards compatibility
|
||||
export const LoginHelper = {
|
||||
login,
|
||||
info: getAccountInfo,
|
||||
logout,
|
||||
}
|
||||
|
||||
export class TokenSession implements Session {
|
||||
@ -91,7 +98,7 @@ export class TokenSession implements Session {
|
||||
data: any,
|
||||
c: EndpointCreator = api_endpoint,
|
||||
): Promise<AxiosResponse> => {
|
||||
let promise
|
||||
let promise: Promise<AxiosResponse>
|
||||
switch (verb.toLowerCase()) {
|
||||
case 'post':
|
||||
promise = axios.post(c(url), data, this.genHeaders())
|
||||
|
||||
@ -20,7 +20,8 @@ const columns = {
|
||||
return c[0].has(row.original.item.id)
|
||||
}, [c])
|
||||
return (
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
className={`no-select flex flex-row ${row.original.status?.selected ? 'animate-pulse' : ''}`}
|
||||
onClick={_e => {
|
||||
setItemSelection({
|
||||
@ -35,7 +36,7 @@ const columns = {
|
||||
className="select-none object-contain select-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
},
|
||||
}),
|
||||
|
||||
@ -187,7 +187,7 @@ export const currentItemSelectionAtom = atom<[Map<string, number>, number]>([
|
||||
export const currentInventorySearchQueryAtom = atom('')
|
||||
|
||||
export const filteredCharacterItemsAtom = atom(get => {
|
||||
const { items, searcher } = get(currentCharacterItemsAtom)
|
||||
const { items } = get(currentCharacterItemsAtom)
|
||||
const [selection] = get(currentItemSelectionAtom)
|
||||
const filter = get(inventoryFilterAtom)
|
||||
const out: ItemWithSelection[] = []
|
||||
@ -202,7 +202,7 @@ export const filteredCharacterItemsAtom = atom(get => {
|
||||
continue
|
||||
}
|
||||
}
|
||||
let status
|
||||
let status: { selected: boolean } | undefined
|
||||
if (selection.has(value.id)) {
|
||||
status = {
|
||||
selected: true,
|
||||
|
||||
@ -68,7 +68,7 @@ export const loadStore = () => {
|
||||
export const saveStore = () => {
|
||||
const store = useStoreRef()
|
||||
for (const [k, v] of Object.entries(StoreReviver)) {
|
||||
let coke
|
||||
let coke: string | undefined
|
||||
if (store[k as keyof RefStore] !== undefined) {
|
||||
coke = v.Murder(store[k as keyof RefStore].value as any)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user