Skip to content

Commit

Permalink
Use <dy-list>
Browse files Browse the repository at this point in the history
  • Loading branch information
mantou132 committed Dec 25, 2023
1 parent 94a1b95 commit 4d56f1a
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 70 deletions.
4 changes: 2 additions & 2 deletions packages/webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
"prepublishOnly": "npm run build"
},
"dependencies": {
"@mantou/gem": "^1.7.4",
"@mantou/gem": "^1.7.5",
"@mantou/nes": "^1.0.14",
"@mantou/nes-sandbox": "^0.0.13",
"@nesbox/arcade": "^0.0.1",
"@nesbox/fceux": "^0.0.1",
"@nesbox/mtapp": "^0.0.1",
"@nesbox/wasm4": "^0.0.1",
"duoyun-ui": "^1.1.4",
"duoyun-ui": "^1.1.5",
"front-matter": "^4.0.2",
"graphql": "^16.2.0",
"jszip": "^3.10.0",
Expand Down
16 changes: 2 additions & 14 deletions packages/webapp/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from '@mantou/gem';
import { hotkeys } from 'duoyun-ui/lib/hotkeys';
import { Loadbar } from 'duoyun-ui/elements/page-loadbar';
import { createPath, RouteItem } from '@mantou/gem/elements/route';
import { createPath } from '@mantou/gem/elements/route';
import { routes, locationStore } from 'src/routes';
import { DuoyunRouteElement } from 'duoyun-ui/elements/route';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';
Expand Down Expand Up @@ -48,18 +48,6 @@ import 'src/modules/friend-list';
import 'src/modules/chat';
import 'src/modules/nav';

const navRoutes: RouteItem[] = [
{
...routes.game,
getContent: (params) => html`<m-nav page="game" id=${params[paramKeys.GAME_ID]}></m-nav>`,
},
{
...routes.room,
content: html`<m-nav page="room"></m-nav>`,
},
{ pattern: '*', content: html`<m-nav></m-nav>` },
];

const style = createCSSSheet(css`
:host {
display: contents;
Expand Down Expand Up @@ -216,7 +204,7 @@ export class AppRootElement extends GemElement {
return html`
${mediaQuery.isPhone ? html`<m-side-nav ?open=${configure.sideNavState}></m-side-nav>` : ''}
<div class=${classMap({ app: true, out: !!configure.sideNavState })}>
<dy-route .locationStore=${locationStore} .routes=${navRoutes}></dy-route>
<m-nav></m-nav>
<div tabindex="-1" class="content" ?inert=${configure.sideNavState} ref=${this.contentRef.ref}>
<main style="display: contents">
<dy-route
Expand Down
20 changes: 20 additions & 0 deletions packages/webapp/src/elements/nav-link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { connectStore, customElement, state } from '@mantou/gem';
import { DuoyunActiveLinkElement } from 'duoyun-ui/elements/link';
import { locationStore } from 'src/routes';

/**
* @customElement nesbox-nav-link
*/
@customElement('nesbox-nav-link')
@connectStore(locationStore)
export class NesboxNavLinkElement extends DuoyunActiveLinkElement {
@state match: boolean;

constructor() {
super();
this.effect(
() => (this.match = this.active),
() => [locationStore.path],
);
}
}
30 changes: 23 additions & 7 deletions packages/webapp/src/modules/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
RefObject,
} from '@mantou/gem';
import { hotkeys } from 'duoyun-ui/lib/hotkeys';
import { fadeOut, commonAnimationOptions } from 'duoyun-ui/lib/animations';

import { changeFriendChatDraft, friendStore, toggleFriendChatState } from 'src/store';
import { createMessage, getMessages, readMessage } from 'src/services/api';
Expand Down Expand Up @@ -39,6 +40,13 @@ const style = createCSSSheet(css`
box-shadow: 0 0.3em 0.75em rgba(0, 0, 0, calc(${theme.maskAlpha} - 0.15));
box-sizing: border-box;
border-radius: ${theme.normalRound};
animation: show 0.15s ${theme.timingFunction} forwards;
}
@keyframes show {
from {
transform: translate(0, 50%);
opacity: 0;
}
}
.header {
display: flex;
Expand Down Expand Up @@ -119,28 +127,36 @@ export class MChatElement extends GemElement {
})(evt);
};

willMount() {
this.memo(
() => (this.inert = !friendStore.friendChatState),
() => [friendStore.friendChatState],
);
}

mounted = () => {
this.effect(
async () => {
if (friendStore.friendChatState) {
await getMessages(friendStore.friendChatState);
}
// 保证用户看到信息后才清除未读
if (friendStore.friendChatState) {
readMessage(friendStore.friendChatState);
// 保证用户看到信息后才清除未读
friendStore.friendChatState && readMessage(friendStore.friendChatState);
} else {
await this.animate(fadeOut, commonAnimationOptions).finished;
this.inert = false;
this.update();
}
},
() => [friendStore.friendChatState],
);
this.effect(
() => {
this.messageRef.element?.scrollTo(0, 10000);
},
() => this.messageRef.element?.scrollTo(0, 10000),
() => [friendStore.messageIds[friendStore.friendChatState || 0]],
);
};

render = () => {
if (this.inert) return undefined;
if (!friendStore.friendChatState) {
return html`
<style>
Expand Down
6 changes: 3 additions & 3 deletions packages/webapp/src/modules/friend-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ const style = createCSSSheet(css`
padding: 0.5em;
gap: 0.5em;
}
:host(:where(:--active, [data-active], :hover, :focus)) {
:host(:where(:state(active), [data-active], :hover, :focus)) {
background-color: ${theme.lightBackgroundColor};
}
:host .action:where(:--active, [data-active], :hover, :focus) {
:host .action:where(:state(active), [data-active], :hover, :focus) {
background-color: ${theme.hoverBackgroundColor};
}
.avatar {
Expand Down Expand Up @@ -57,7 +57,7 @@ const style = createCSSSheet(css`
padding: 0.2em;
}
:host(:hover) .action,
.action:where(:--active, [data-active], :hover) {
.action:where(:state(active), [data-active], :hover) {
display: inline-flex;
}
`);
Expand Down
1 change: 1 addition & 0 deletions packages/webapp/src/modules/friend-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class MFriendListElement extends GemElement {
});
applyFriend(input.value);
} finally {
// use `focusVisible: false`
activeElement?.focus();
}
};
Expand Down
9 changes: 2 additions & 7 deletions packages/webapp/src/modules/game-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import 'duoyun-ui/elements/modal';
const style = createCSSSheet(css`
:host {
position: relative;
display: block;
}
.actions {
position: absolute;
Expand Down Expand Up @@ -101,13 +102,7 @@ export class MGameItemElement extends GemElement {

render = () => {
return html`
<img
draggable="false"
class="cover"
loading="lazy"
@click=${this.#onMoreClick}
src=${getCDNSrc(this.game.preview)}
/>
<img draggable="false" class="cover" @click=${this.#onMoreClick} src=${getCDNSrc(this.game.preview)} />
<dy-space class="actions" size="small">
<dy-button data-cy="start" class="play" small ?hidden=${mediaQuery.isPhone} @click=${this.#onGameClick}>
${i18n.get('page.game.start')}
Expand Down
52 changes: 42 additions & 10 deletions packages/webapp/src/modules/game-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import {
css,
connectStore,
boolattribute,
repeat,
styleMap,
numattribute,
RefObject,
refobject,
history,
} from '@mantou/gem';
import { isNotNullish } from 'duoyun-ui/lib/types';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';
Expand All @@ -25,10 +27,13 @@ import { gameKindList, gameSeriesList } from 'src/enums';
import { ScGameKind, ScGameSeries } from 'src/generated/graphql';
import { icons } from 'src/icons';

import type { DuoyunListElement, PersistentState } from 'duoyun-ui/elements/list';

import 'duoyun-ui/elements/heading';
import 'duoyun-ui/elements/divider';
import 'duoyun-ui/elements/select';
import 'duoyun-ui/elements/picker';
import 'duoyun-ui/elements/list';
import 'duoyun-ui/elements/use';
import 'src/modules/game-item';

Expand All @@ -52,7 +57,7 @@ const style = createCSSSheet(css`
align-items: center;
gap: 1em;
}
.list {
.list::part(list) {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(12em, 1fr));
grid-template-rows: max-content;
Expand All @@ -66,15 +71,21 @@ const style = createCSSSheet(css`
}
`);

// 只缓存 all 列表,不然串数据
let persistentState: PersistentState | undefined;

/**
* @customElement m-game-list
*/
@customElement('m-game-list')
@adoptedStyle(style)
@connectStore(store)
@connectStore(locationStore)
@connectStore(history.store)
@connectStore(i18n.store)
export class MGameListElement extends GemElement {
@refobject listRef: RefObject<DuoyunListElement>;

@boolattribute favorite: boolean;
@boolattribute recent: boolean;
@boolattribute new: boolean;
Expand Down Expand Up @@ -125,6 +136,14 @@ export class MGameListElement extends GemElement {
}
};

#renderItem = (id: number) => {
const game = store.games[id];
if (!game) return html``;
return html`<m-game-item .game=${game} .favorited=${this.#favSet.has(id)}></m-game-item>`;
};

#getKey = (id: number) => id;

#filteredData?: number[] = [];
willMount = () => {
this.memo(
Expand Down Expand Up @@ -165,6 +184,17 @@ export class MGameListElement extends GemElement {
);
};

mounted = () => {
this.effect(
() => {
if (this.all) {
persistentState = this.listRef.element?.persistentState;
}
},
() => [history.getParams().path],
);
};

render = () => {
if ((this.recent || this.new) && (!this.#data || this.#data.length < 4)) {
return html`
Expand Down Expand Up @@ -249,14 +279,16 @@ export class MGameListElement extends GemElement {
</div>
<dy-divider></dy-divider>
`}
<div class="list">
${repeat(
this.#filteredData || [],
(id) =>
store.games[id] &&
html`<m-game-item .game=${store.games[id]!} .favorited=${this.#favSet.has(id)}></m-game-item>`,
)}
</div>
<dy-list
class="list"
ref=${this.listRef.ref}
.items=${this.#filteredData}
.key=${store.favoriteIds}
.infinite=${this.all}
.getKey=${this.#getKey}
.renderItem=${this.#renderItem}
.persistentState=${this.all ? persistentState : undefined}
></dy-list>
`;
};
}
2 changes: 1 addition & 1 deletion packages/webapp/src/modules/guest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const style = createCSSSheet(css`
padding: 4px;
border-radius: ${theme.normalRound};
}
.menu:where(:hover, :--active, [data-active]) {
.menu:where(:hover, :state(active), [data-active]) {
background-color: ${theme.hoverBackgroundColor};
}
`);
Expand Down
2 changes: 1 addition & 1 deletion packages/webapp/src/modules/invite-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const style = createCSSSheet(css`
padding: 0.2em;
opacity: 0.7;
}
.action:where(:--active, [data-active], :hover, :focus) {
.action:where(:state(active), [data-active], :hover, :focus) {
opacity: 1;
}
.invite-tip {
Expand Down
6 changes: 3 additions & 3 deletions packages/webapp/src/modules/msg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const style = createCSSSheet(css`
flex-direction: column;
align-items: flex-start;
}
:host(:where(:--self, [data-self])) {
:host(:where(:state(self), [data-self])) {
align-items: flex-end;
}
.body {
Expand All @@ -32,7 +32,7 @@ const style = createCSSSheet(css`
background-color: ${theme.noticeColor};
border-radius: ${theme.smallRound};
}
:host(:where(:--self, [data-self])) .body {
:host(:where(:state(self), [data-self])) .body {
background-color: ${theme.describeColor};
}
:host([last]) {
Expand All @@ -48,7 +48,7 @@ const style = createCSSSheet(css`
left: 0;
border-inline-color: ${theme.noticeColor} transparent;
}
:host(:is(:--self, [data-self])) .body::after {
:host(:is(:state(self), [data-self])) .body::after {
left: auto;
right: 0;
border-inline-color: transparent ${theme.describeColor};
Expand Down
2 changes: 1 addition & 1 deletion packages/webapp/src/modules/mt-nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const style = createCSSSheet(css`
opacity: 0.5;
outline: none;
}
.link:where(:--active, [data-active]) {
.link:where(:state(active), [data-active]) {
opacity: 1;
}
.status {
Expand Down
Loading

0 comments on commit 4d56f1a

Please sign in to comment.