Commit 0c0079b6 authored by timel's avatar timel

Merge branch 'dev/callalily' into 'main'

fetchCard/searchCard改为同步

See merge request mycard/Neos!277
parents 270df721 19073671
Pipeline #23227 passed with stages
in 10 minutes and 10 seconds
...@@ -50,8 +50,8 @@ export interface CardText { ...@@ -50,8 +50,8 @@ export interface CardText {
* @returns 卡片数据 * @returns 卡片数据
* *
* */ * */
export async function fetchCard(id: number): Promise<CardMeta> { export function fetchCard(id: number): CardMeta {
const res = await sqliteMiddleWare({ const res = sqliteMiddleWare({
cmd: sqliteCmd.SELECT, cmd: sqliteCmd.SELECT,
payload: { id }, payload: { id },
}); });
...@@ -65,8 +65,8 @@ export async function fetchCard(id: number): Promise<CardMeta> { ...@@ -65,8 +65,8 @@ export async function fetchCard(id: number): Promise<CardMeta> {
* @returns 卡片数据 * @returns 卡片数据
* *
* */ * */
export async function searchCards(params: FtsParams): Promise<CardMeta[]> { export function searchCards(params: FtsParams): CardMeta[] {
const res = await sqliteMiddleWare({ const res = sqliteMiddleWare({
cmd: sqliteCmd.FTS, cmd: sqliteCmd.FTS,
payload: { ftsParams: params }, payload: { ftsParams: params },
}); });
......
...@@ -36,6 +36,6 @@ export async function getStrings(description: number): Promise<string> { ...@@ -36,6 +36,6 @@ export async function getStrings(description: number): Promise<string> {
const code = description >> 4; const code = description >> 4;
const index = description & 0xf; const index = description & 0xf;
return getCardStr(await fetchCard(code), index) || ""; return getCardStr(fetchCard(code), index) || "";
} }
} }
...@@ -24,8 +24,8 @@ export enum sqliteCmd { ...@@ -24,8 +24,8 @@ export enum sqliteCmd {
FTS, FTS,
} }
export interface sqliteAction { export interface sqliteAction<T extends sqliteCmd> {
cmd: sqliteCmd; cmd: T;
// 初始化DB需要业务方传入的数据 // 初始化DB需要业务方传入的数据
initInfo?: { initInfo?: {
dbUrl: string; dbUrl: string;
...@@ -47,8 +47,14 @@ const sqlPromise = initSqlJs({ ...@@ -47,8 +47,14 @@ const sqlPromise = initSqlJs({
locateFile: (file) => `${NeosConfig.assetsPath}/${file}`, locateFile: (file) => `${NeosConfig.assetsPath}/${file}`,
}); });
export default function <T extends sqliteCmd>(
action: sqliteAction<T>,
): T extends sqliteCmd.INIT ? Promise<void> : sqliteResult {
return helper(action) as any;
}
// FIXME: 应该有个返回值,告诉业务方本次请求的结果,比如初始化DB失败 // FIXME: 应该有个返回值,告诉业务方本次请求的结果,比如初始化DB失败
export default async function (action: sqliteAction): Promise<sqliteResult> { function helper<T extends sqliteCmd>(action: sqliteAction<T>) {
switch (action.cmd) { switch (action.cmd) {
case sqliteCmd.INIT: { case sqliteCmd.INIT: {
const info = action.initInfo; const info = action.initInfo;
...@@ -56,16 +62,14 @@ export default async function (action: sqliteAction): Promise<sqliteResult> { ...@@ -56,16 +62,14 @@ export default async function (action: sqliteAction): Promise<sqliteResult> {
const dataPromise = pfetch(info.dbUrl, { const dataPromise = pfetch(info.dbUrl, {
progressCallback: action.initInfo?.progressCallback, progressCallback: action.initInfo?.progressCallback,
}).then((res) => res.arrayBuffer()); // TODO: i18n }).then((res) => res.arrayBuffer()); // TODO: i18n
return Promise.all([sqlPromise, dataPromise]).then(([SQL, buffer]) => {
const [SQL, buffer] = await Promise.all([sqlPromise, dataPromise]); YGODB = new SQL.Database(new Uint8Array(buffer));
YGODB = new SQL.Database(new Uint8Array(buffer)); console.log("YGODB inited!");
});
console.info("YGODB inited!");
} else { } else {
console.warn("init YGODB action without initInfo"); console.warn("init YGODB action without initInfo");
return {};
} }
return {};
} }
case sqliteCmd.SELECT: { case sqliteCmd.SELECT: {
if (YGODB && action.payload && action.payload.id) { if (YGODB && action.payload && action.payload.id) {
......
...@@ -40,7 +40,7 @@ export default async (announce: MsgAnnounce) => { ...@@ -40,7 +40,7 @@ export default async (announce: MsgAnnounce) => {
case MsgAnnounce.AnnounceType.Card: { case MsgAnnounce.AnnounceType.Card: {
const options = []; const options = [];
for (const option of announce.options) { for (const option of announce.options) {
const meta = await fetchCard(option.code); const meta = fetchCard(option.code);
if (meta.text.name) { if (meta.text.name) {
options.push({ options.push({
info: meta.text.name, info: meta.text.name,
......
...@@ -18,7 +18,7 @@ export default async (chaining: ygopro.StocGameMessage.MsgChaining) => { ...@@ -18,7 +18,7 @@ export default async (chaining: ygopro.StocGameMessage.MsgChaining) => {
// 设置连锁序号 // 设置连锁序号
target.chainIndex = matStore.chains.length; target.chainIndex = matStore.chains.length;
const meta = await fetchCard(chaining.code); const meta = fetchCard(chaining.code);
// 这里不能设置`code`,因为存在一个场景: // 这里不能设置`code`,因为存在一个场景:
// 对方的`魔神仪-曼德拉护肤草`发动效果后,后端会发一次`MSG_SHUFFLE_HAND`,但传给前端的codes全是0,如果这里设置了`code`的话,在后面的`MSG_SHUFFLE_HAND`处理就会有问题。 // 对方的`魔神仪-曼德拉护肤草`发动效果后,后端会发一次`MSG_SHUFFLE_HAND`,但传给前端的codes全是0,如果这里设置了`code`的话,在后面的`MSG_SHUFFLE_HAND`处理就会有问题。
// target.code = meta.id; // target.code = meta.id;
......
...@@ -11,7 +11,7 @@ export default async (confirmCards: ygopro.StocGameMessage.MsgConfirmCards) => { ...@@ -11,7 +11,7 @@ export default async (confirmCards: ygopro.StocGameMessage.MsgConfirmCards) => {
if (target) { if (target) {
// 设置`occupant` // 设置`occupant`
const meta = await fetchCard(card.code); const meta = fetchCard(card.code);
target.meta = meta; target.meta = meta;
// 动画 // 动画
await callCardFocus(target.uuid); await callCardFocus(target.uuid);
......
...@@ -17,7 +17,7 @@ export default async (draw: ygopro.StocGameMessage.MsgDraw) => { ...@@ -17,7 +17,7 @@ export default async (draw: ygopro.StocGameMessage.MsgDraw) => {
for (const idx in newHands) { for (const idx in newHands) {
const card = newHands[Number(idx)]; const card = newHands[Number(idx)];
const code = draw.cards[idx]; const code = draw.cards[idx];
const meta = await fetchCard(code); const meta = fetchCard(code);
card.code = code; card.code = code;
card.meta = meta; card.meta = meta;
card.location.zone = ygopro.CardZone.HAND; card.location.zone = ygopro.CardZone.HAND;
......
...@@ -34,7 +34,7 @@ export default async (move: MsgMove) => { ...@@ -34,7 +34,7 @@ export default async (move: MsgMove) => {
const to = move.to; const to = move.to;
const reason = move.reason; const reason = move.reason;
const meta = await fetchCard(code); const meta = fetchCard(code);
if (meta.data.type !== undefined && (meta.data.type & TYPE_TOKEN) > 0) { if (meta.data.type !== undefined && (meta.data.type & TYPE_TOKEN) > 0) {
// 衍生物 // 衍生物
if (from.zone === DECK) { if (from.zone === DECK) {
......
...@@ -32,6 +32,6 @@ export default async (selectEffectYn: MsgSelectEffectYn) => { ...@@ -32,6 +32,6 @@ export default async (selectEffectYn: MsgSelectEffectYn) => {
// TODO: 国际化文案 // TODO: 国际化文案
const desc = fetchStrings(Region.System, effect_description); const desc = fetchStrings(Region.System, effect_description);
const meta = await fetchCard(code); const meta = fetchCard(code);
await displayYesNoModal(textGenerator(desc, meta, location)); await displayYesNoModal(textGenerator(desc, meta, location));
}; };
...@@ -13,7 +13,7 @@ export default async (selectOption: ygopro.StocGameMessage.MsgSelectOption) => { ...@@ -13,7 +13,7 @@ export default async (selectOption: ygopro.StocGameMessage.MsgSelectOption) => {
fetchStrings(Region.System, 556), fetchStrings(Region.System, 556),
await Promise.all( await Promise.all(
options.map(async ({ code, response }) => { options.map(async ({ code, response }) => {
const meta = await fetchCard(code >> 4); const meta = fetchCard(code >> 4);
const msg = getCardStr(meta, code & 0xf) || "[?]"; const msg = getCardStr(meta, code & 0xf) || "[?]";
return { msg, response }; return { msg, response };
}), }),
......
...@@ -6,7 +6,7 @@ type MsgSortCard = ygopro.StocGameMessage.MsgSortCard; ...@@ -6,7 +6,7 @@ type MsgSortCard = ygopro.StocGameMessage.MsgSortCard;
export default async (sortCard: MsgSortCard) => { export default async (sortCard: MsgSortCard) => {
const options = await Promise.all( const options = await Promise.all(
sortCard.options.map(async ({ code, response }) => { sortCard.options.map(async ({ code, response }) => {
const meta = await fetchCard(code!); const meta = fetchCard(code!);
return { return {
meta, meta,
response: response!, response: response!,
......
...@@ -106,7 +106,7 @@ export default async (start: ygopro.StocGameMessage.MsgStart) => { ...@@ -106,7 +106,7 @@ export default async (start: ygopro.StocGameMessage.MsgStart) => {
const genCard = (o: CardType) => { const genCard = (o: CardType) => {
const t = proxy(o); const t = proxy(o);
subscribeKey(t, "code", async (code) => { subscribeKey(t, "code", async (code) => {
const meta = await fetchCard(code ?? 0); const meta = fetchCard(code ?? 0);
t.meta = meta; t.meta = meta;
}); });
return t; return t;
......
...@@ -16,7 +16,7 @@ export default async (updateData: MsgUpdateData) => { ...@@ -16,7 +16,7 @@ export default async (updateData: MsgUpdateData) => {
if (target) { if (target) {
// 目前只更新以下字段 // 目前只更新以下字段
if (action?.code >= 0) { if (action?.code >= 0) {
const newMeta = await fetchCard(action.code); const newMeta = fetchCard(action.code);
target.code = action.code; target.code = action.code;
target.meta = newMeta; target.meta = newMeta;
} }
......
...@@ -24,7 +24,7 @@ export default async function handleErrorMsg(errorMsg: ygopro.StocErrorMsg) { ...@@ -24,7 +24,7 @@ export default async function handleErrorMsg(errorMsg: ygopro.StocErrorMsg) {
case ErrorType.DECKERROR: { case ErrorType.DECKERROR: {
const flag = error_code >> 28; const flag = error_code >> 28;
const code = error_code && 0xfffffff; const code = error_code && 0xfffffff;
const card = await fetchCard(code); const card = fetchCard(code);
const baseMsg = `卡组非法,请检查:${card.text.name}`; const baseMsg = `卡组非法,请检查:${card.text.name}`;
switch (flag) { switch (flag) {
case DECKERROR_LFLIST: { case DECKERROR_LFLIST: {
......
...@@ -30,7 +30,7 @@ const helper = async ( ...@@ -30,7 +30,7 @@ const helper = async (
code !== 0 code !== 0
? code ? code
: cardStore.at(location.zone, controller, location.sequence)?.code || 0; : cardStore.at(location.zone, controller, location.sequence)?.code || 0;
const meta = await fetchCard(newID); const meta = fetchCard(newID);
const effectDesc = effect_description const effectDesc = effect_description
? getCardStr(meta, effect_description & 0xf) ? getCardStr(meta, effect_description & 0xf)
......
...@@ -22,7 +22,7 @@ export const fetchSelectHintMeta = async ({ ...@@ -22,7 +22,7 @@ export const fetchSelectHintMeta = async ({
let selectHintMeta = ""; let selectHintMeta = "";
if (selectHintData > DESCRIPTION_LIMIT) { if (selectHintData > DESCRIPTION_LIMIT) {
// 针对`MSG_SELECT_PLACE`的特化逻辑 // 针对`MSG_SELECT_PLACE`的特化逻辑
const cardMeta = await fetchCard(selectHintData); const cardMeta = fetchCard(selectHintData);
selectHintMeta = fetchStrings(Region.System, 569).replace( selectHintMeta = fetchStrings(Region.System, 569).replace(
"[%ls]", "[%ls]",
cardMeta.text.name || "[?]", cardMeta.text.name || "[?]",
...@@ -55,7 +55,7 @@ export const fetchEsHintMeta = async ({ ...@@ -55,7 +55,7 @@ export const fetchEsHintMeta = async ({
? originMsg ? originMsg
: fetchStrings(Region.System, originMsg); : fetchStrings(Region.System, originMsg);
const cardMeta = cardID ? await fetchCard(cardID) : undefined; const cardMeta = cardID ? fetchCard(cardID) : undefined;
let esHint = newOriginMsg; let esHint = newOriginMsg;
......
...@@ -23,7 +23,7 @@ export const CardDetail: React.FC<{ ...@@ -23,7 +23,7 @@ export const CardDetail: React.FC<{
}> = ({ code, open, onClose }) => { }> = ({ code, open, onClose }) => {
const [card, setCard] = useState<CardMeta>(); const [card, setCard] = useState<CardMeta>();
useEffect(() => { useEffect(() => {
fetchCard(code).then(setCard); setCard(fetchCard(code));
}, [code]); }, [code]);
const cardType = useMemo( const cardType = useMemo(
() => () =>
......
...@@ -262,8 +262,8 @@ const Search: React.FC = () => { ...@@ -262,8 +262,8 @@ const Search: React.FC = () => {
] as const ] as const
).map(([label, onClick], key) => ({ key, label, onClick })); ).map(([label, onClick], key) => ({ key, label, onClick }));
const handleSearch = async (conditions: FtsConditions = searchConditions) => { const handleSearch = (conditions: FtsConditions = searchConditions) => {
const result = (await searchCards({ query: searchWord, conditions })) const result = searchCards({ query: searchWord, conditions })
.filter((card) => !isToken(card.data.type ?? 0)) .filter((card) => !isToken(card.data.type ?? 0))
.sort(sortRef.current); // 衍生物不显示 .sort(sortRef.current); // 衍生物不显示
setSearchResult(() => result); setSearchResult(() => result);
......
...@@ -54,9 +54,15 @@ ...@@ -54,9 +54,15 @@
.inner { .inner {
position: absolute; position: absolute;
left: 0; left: 0;
width: 150px;
height: 70px;
filter: blur(120px);
transition: 0.3s;
}
&.ready .inner {
width: 250px; width: 250px;
height: 100px; height: 100px;
filter: blur(120px); filter: blur(100px) brightness(1.2) saturate(1.2);
} }
&.me { &.me {
box-shadow: -5px 0 20px 0 rgba(0, 115, 255, 0.15); box-shadow: -5px 0 20px 0 rgba(0, 115, 255, 0.15);
......
...@@ -99,6 +99,7 @@ export const Component: React.FC = () => { ...@@ -99,6 +99,7 @@ export const Component: React.FC = () => {
who={Who.Me} who={Who.Me}
player={me} player={me}
avatar={user?.avatar_url} avatar={user?.avatar_url}
ready={me?.state === PlayerState.READY}
btn={ btn={
room.stage === RoomStage.WAITING ? ( room.stage === RoomStage.WAITING ? (
<Button <Button
...@@ -144,6 +145,7 @@ export const Component: React.FC = () => { ...@@ -144,6 +145,7 @@ export const Component: React.FC = () => {
key={idx} key={idx}
who={Who.Op} who={Who.Op}
player={player} player={player}
ready={op?.state === PlayerState.READY}
btn={ btn={
room.stage === RoomStage.WAITING ? null : ( room.stage === RoomStage.WAITING ? null : (
<MoraAvatar <MoraAvatar
...@@ -183,12 +185,17 @@ enum Who { ...@@ -183,12 +185,17 @@ enum Who {
// 玩家区域: 双方各有一个 // 玩家区域: 双方各有一个
const PlayerZone: React.FC<{ const PlayerZone: React.FC<{
btn?: React.ReactNode; // 在内部右侧可以放一个按钮 btn?: React.ReactNode; // 在内部右侧可以放一个按钮
who?: Who; who: Who;
player?: Player; player?: Player;
avatar?: string; // 因为对手的头像目前不清楚如何获取,因此暂时这里作为一个参数传入 avatar?: string; // 因为对手的头像目前不清楚如何获取,因此暂时这里作为一个参数传入
}> = ({ btn, who, player, avatar }) => { ready: boolean;
}> = ({ btn, who, player, avatar, ready }) => {
return ( return (
<div className={classNames(styles["side-box"], who && styles[who])}> <div
className={classNames(styles["side-box"], styles[who], {
[styles.ready]: ready,
})}
>
<div className={styles.inner}></div> <div className={styles.inner}></div>
<div style={{ position: "relative" }}> <div style={{ position: "relative" }}>
<Avatar <Avatar
...@@ -364,7 +371,10 @@ const ActionButton: React.FC<{ ...@@ -364,7 +371,10 @@ const ActionButton: React.FC<{
<span>等待游戏开始</span> <span>等待游戏开始</span>
</> </>
) : ( ) : (
<></> <>
<LoadingOutlined />
<span>等待游戏开始</span>
</>
)} )}
</SpecialButton> </SpecialButton>
</TpPopover> </TpPopover>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment