@vnejs/plugins.view.coralina.gamemenu 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ export const SUBSCRIBE_EVENTS = {
2
+ SHOW: "vne:gamemenu_view:show",
3
+ HIDE: "vne:gamemenu_view:hide",
4
+ CLICK: "vne:gamemenu_view:click",
5
+ ACCEPT: "vne:gamemenu_view:accept",
6
+ UPDATE: "vne:gamemenu_view:update",
7
+ };
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ import { regPlugin } from "@vnejs/shared";
2
+
3
+ import { SUBSCRIBE_EVENTS } from "./const/events";
4
+
5
+ import { GameMenuController } from "./modules/controller";
6
+ import { GameMenuView } from "./modules/view";
7
+
8
+ regPlugin("GAMEMENU_VIEW", { events: SUBSCRIBE_EVENTS }, [GameMenuController, GameMenuView]);
@@ -0,0 +1,58 @@
1
+ import { Module } from "@vnejs/module";
2
+
3
+ const toStateItem = ({ onClick, ...item }) => item;
4
+ const onRealItems = (item) => !item.isDisabled && !item.isHide;
5
+
6
+ export class GameMenuController extends Module.Controller {
7
+ name = "gameMenu.controller";
8
+
9
+ updateEvent = this.EVENTS.GAMEMENU_VIEW.UPDATE;
10
+ controls = {
11
+ [this.CONST.CONTROLS.BUTTONS.BACK]: () => this.emit(this.EVENTS.GAMEMENU.HIDE),
12
+ [this.CONST.CONTROLS.BUTTONS.MENU]: () => this.emit(this.EVENTS.GAMEMENU.HIDE),
13
+ [this.CONST.CONTROLS.BUTTONS.GAMEMENU]: () => this.emit(this.EVENTS.GAMEMENU.HIDE),
14
+ [this.CONST.CONTROLS.BUTTONS.ACCEPT]: () => this.emit(this.EVENTS.GAMEMENU_VIEW.ACCEPT),
15
+ [this.CONST.CONTROLS.BUTTONS.ARROW_UP]: this.decCurrentItem,
16
+ [this.CONST.CONTROLS.BUTTONS.ARROW_BOTTOM]: this.incCurrentItem,
17
+ };
18
+ controlsIndex = 3000;
19
+
20
+ subscribe = () => {
21
+ this.on(this.EVENTS.GAMEMENU_VIEW.CLICK, this.onClick);
22
+ this.on(this.EVENTS.GAMEMENU_VIEW.ACCEPT, this.onAccept);
23
+
24
+ this.on(this.EVENTS.GAMEMENU.SHOW, this.onShow);
25
+ this.on(this.EVENTS.GAMEMENU.HIDE, this.onHide);
26
+
27
+ this.on(this.EVENTS.LOCS.LANG_CHANGED, this.onLangChanged);
28
+
29
+ this.on(this.EVENTS.STATE.SET, this.onHideForce);
30
+ this.on(this.EVENTS.STATE.CLEAR, this.onHideForce);
31
+ };
32
+
33
+ beforeShow = async () => {
34
+ await this.updateStateItems();
35
+
36
+ this.currentItem = null;
37
+ this.maxCurrentItem = this.state.realItems.length - 1;
38
+ };
39
+
40
+ onLangChanged = () => this.updateStateItems().then(this.updateViewFast);
41
+
42
+ onAccept = async () => this.click((await this.getItems()).filter(onRealItems), this.currentItem);
43
+ onClick = async ({ index } = {}) => this.click(await this.getItems(), index);
44
+
45
+ click = (items, index) => index !== null && items[index] && items[index].onClick && items[index].onClick();
46
+
47
+ getItems = async () => {
48
+ const [items] = await this.emit(this.EVENTS.GAMEMENU.ITEMS);
49
+
50
+ return items;
51
+ };
52
+
53
+ updateStateItems = async () => {
54
+ const items = (await this.getItems()).map(toStateItem);
55
+
56
+ this.updateState({ items, realItems: items.filter(onRealItems) });
57
+ };
58
+ }
@@ -0,0 +1,12 @@
1
+ import { Module } from "@vnejs/module";
2
+
3
+ import { render } from "../view";
4
+
5
+ export class GameMenuView extends Module.View {
6
+ name = "gameMenu.view";
7
+ locLabel = "gameMenu";
8
+ animationTime = 300;
9
+ renderFunc = render;
10
+ updateEvent = this.EVENTS.GAMEMENU_VIEW.UPDATE;
11
+ updateHandler = this.onUpdateReactComponent;
12
+ }
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@vnejs/plugins.view.coralina.gamemenu",
3
+ "version": "0.0.1",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "publish:major": "npm version major && npm publish --access public",
8
+ "publish:minor": "npm version minor && npm publish --access public",
9
+ "publish:patch": "npm version patch && npm publish --access public"
10
+ },
11
+ "author": "",
12
+ "license": "ISC",
13
+ "description": "",
14
+ "peerDependencies": {
15
+ "@vnejs/shared": "*",
16
+ "@vnejs/module": "*"
17
+ }
18
+ }
package/view/index.jsx ADDED
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom";
3
+
4
+ import { cn } from "@bem-react/classname";
5
+
6
+ import "./index.styl";
7
+
8
+ const b = cn("GameMenu");
9
+
10
+ class GameMenu extends React.Component {
11
+ state = {};
12
+
13
+ onClick = ({ currentTarget: { dataset: { index = 0 } = {} } = {} }) =>
14
+ this.props.emit(this.props.EVENTS.GAMEMENU_VIEW.CLICK, { index });
15
+
16
+ renderItem = ({ locKey, isDisabled, isHide }, i) => {
17
+ const { currentItem = null, locs = {}, realItems = [] } = this.state;
18
+ const isCurrent = currentItem !== null && realItems[currentItem].locKey === locKey;
19
+
20
+ if (isHide) return;
21
+ return (
22
+ <div
23
+ className={b("button", { isCurrent, isDisabled }, ["textWrap_72"])}
24
+ onClick={isDisabled ? undefined : this.onClick}
25
+ data-index={i}
26
+ key={locKey}
27
+ >
28
+ <span className="text">{locs[locKey]}</span>
29
+ </div>
30
+ );
31
+ };
32
+
33
+ render() {
34
+ const { isShow = false, isForce = false, items = [] } = this.state;
35
+
36
+ return (
37
+ <div className={b({ isShow, isForce })} data-html2canvas-ignore="1" vne-autoread-disable={isShow ? "1" : ""}>
38
+ <div className={b("menu")}>{items.map(this.renderItem)}</div>
39
+ </div>
40
+ );
41
+ }
42
+ }
43
+
44
+ export const render = (props, root, resolve) => ReactDOM.render(<GameMenu {...props} />, root, resolve);
@@ -0,0 +1,44 @@
1
+ .GameMenu
2
+ display: flex
3
+ justify-content: center
4
+ align-items: center
5
+ position: absolute
6
+ top: 0
7
+ right: 0
8
+ bottom: 0
9
+ left: 0
10
+ backdrop-filter: blur(5px) brightness(0.5)
11
+ opacity: 0
12
+ z-index: 4000
13
+ pointer-events: none
14
+ font-family: 'Montserrat'
15
+
16
+ &-menu
17
+ display: flex
18
+ flex-direction: column
19
+ justify-content: center
20
+ align-items: center
21
+ height: 100%
22
+ gap: 2.5%
23
+
24
+ &-button
25
+ cursor: pointer
26
+ text-align: center
27
+ box-sizing: border-box
28
+ color: rgba(255,255,255,0.6)
29
+ width: 100%
30
+ font-weight: 400
31
+ transition: transform 300ms, text-shadow 300ms, color 300ms
32
+
33
+ &_isCurrent,
34
+ &:hover
35
+ transform: scale(1.5)
36
+ color: rgba(255,255,255,0.85)
37
+ text-shadow: 0px 5px 25px rgba(255,255,255,0.75)
38
+
39
+ &_isShow
40
+ opacity: 1
41
+ pointer-events: all
42
+
43
+ &:not(&_isForce)
44
+ transition: opacity 500ms