Compare commits

..

No commits in common. "3f4318e1931e0d5bc355deb5461ee464a75934a4" and "30a785eabbd060aa228f26e68486123351daca52" have entirely different histories.

4 changed files with 74 additions and 94 deletions

View File

@ -1,78 +0,0 @@
import { Emitter, EventType } from "@Model/Emitter";
import { Component, FunctionComponent, ReactNode, Consumer } from "react";
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
function superConnectWithEvent<C extends Emitter<E>, E extends Record<EventType, any>>(
consumer: Consumer<C>, keyName: string
) {
return (...events: Array<keyof E>) => {
return <R extends RenderComponent>(components: R): R => {
const Components = components as any;
const Consumer = consumer;
return class extends Component<R> {
private status: C | undefined;
private isEventMount: boolean = false;
private propsObject: Record<string, C> = {};
private handelChange = () => {
this.forceUpdate();
}
private mountEvent() {
if (this.status && !this.isEventMount) {
this.isEventMount = true;
console.log("Component dep event mount: " + events.join(", "));
for (let i = 0; i < events.length; i++) {
this.status.on(events[i], this.handelChange);
}
}
}
private unmountEvent() {
if (this.status) {
for (let i = 0; i < events.length; i++) {
this.status.off(events[i], this.handelChange);
}
}
}
public render(): ReactNode {
return <Consumer>
{(status: C) => {
this.status = status;
this.propsObject[keyName] = status;
this.mountEvent();
return <Components {...this.props} {...this.propsObject}/>;
}}
</Consumer>
}
public componentWillUnmount() {
this.unmountEvent();
}
} as any;
}
}
}
function superConnect<C extends Emitter<any>>(consumer: Consumer<C>, keyName: string) {
return <R extends RenderComponent>(components: R): R => {
return ((props: any) => {
const Components = components as any;
const Consumer = consumer;
return <Consumer>
{(status: C) => <Components
{...props}
{...{[keyName]: status}}
/>}
</Consumer>
}) as any;
}
}
export { superConnectWithEvent, superConnect };

View File

@ -1,5 +1,4 @@
import { createContext } from "react"; import { createContext, Component, FunctionComponent } from "react";
import { superConnect, superConnectWithEvent } from "./Context";
import { Emitter } from "@Model/Emitter"; import { Emitter } from "@Model/Emitter";
import { Layout } from "@Model/Layout"; import { Layout } from "@Model/Layout";
@ -13,11 +12,9 @@ enum Themes {
type Language = "ZH_CN" | "EN_US"; type Language = "ZH_CN" | "EN_US";
interface ISettingEvents extends Setting { class Setting extends Emitter<
change: keyof Setting; Setting & {change: keyof Setting}
} > {
class Setting extends Emitter<ISettingEvents> {
/** /**
* *
@ -54,14 +51,21 @@ SettingContext.displayName = "Setting";
const SettingProvider = SettingContext.Provider; const SettingProvider = SettingContext.Provider;
const SettingConsumer = SettingContext.Consumer; const SettingConsumer = SettingContext.Consumer;
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
/** /**
* *
*/ */
const useSetting = superConnect<Setting>(SettingConsumer, "setting"); function useSetting<R extends RenderComponent>(components: R): R {
return ((props: any) => {
const useStatusWithEvent = superConnectWithEvent<Setting, ISettingEvents>(SettingConsumer, "setting"); const C = components;
return <SettingConsumer>
{(setting: Setting) => <C {...props} setting={setting}></C>}
</SettingConsumer>
}) as any;
}
export { export {
Themes, Setting, SettingContext, useSetting, Language, useStatusWithEvent, Themes, Setting, SettingContext, useSetting, Language,
IMixinSettingProps, SettingProvider, SettingConsumer IMixinSettingProps, SettingProvider, SettingConsumer
}; };

View File

@ -1,4 +1,4 @@
import { createContext, Component, FunctionComponent, ReactNode } from "react"; import { createContext, Component, FunctionComponent, useState, useEffect, ReactNode } from "react";
import { Emitter } from "@Model/Emitter"; import { Emitter } from "@Model/Emitter";
import { Model, ObjectID } from "@Model/Model"; import { Model, ObjectID } from "@Model/Model";
import { Label } from "@Model/Label"; import { Label } from "@Model/Label";
@ -9,7 +9,6 @@ import { AbstractRenderer } from "@Model/Renderer";
import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer";
import { Setting } from "./Setting"; import { Setting } from "./Setting";
import { I18N } from "@Component/Localization/Localization"; import { I18N } from "@Component/Localization/Localization";
import { superConnectWithEvent, superConnect } from "./Context";
function randomColor(unNormal: boolean = false) { function randomColor(unNormal: boolean = false) {
const color = [ const color = [
@ -259,12 +258,67 @@ StatusContext.displayName = "Status";
const StatusProvider = StatusContext.Provider; const StatusProvider = StatusContext.Provider;
const StatusConsumer = StatusContext.Consumer; const StatusConsumer = StatusContext.Consumer;
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
/** /**
* *
*/ */
const useStatus = superConnect<Status>(StatusConsumer, "status"); function useStatus<R extends RenderComponent>(components: R): R {
return ((props: any) => {
const C = components;
return <StatusConsumer>
{(status: Status) => <C {...props} status={status}></C>}
</StatusConsumer>
}) as any;
}
const useStatusWithEvent = superConnectWithEvent<Status, IStatusEvent>(StatusConsumer, "status"); function useStatusWithEvent(...events: Array<keyof IStatusEvent>) {
return <R extends RenderComponent>(components: R): R => {
const C = components as any;
return class extends Component<R> {
private status: Status | undefined;
private isEventMount: boolean = false;
private handelChange = () => {
this.forceUpdate();
}
private mountEvent() {
if (this.status && !this.isEventMount) {
this.isEventMount = true;
console.log("Component dep event mount: " + events.join(", "));
for (let i = 0; i < events.length; i++) {
this.status.on(events[i], this.handelChange);
}
}
}
private unmountEvent() {
if (this.status) {
for (let i = 0; i < events.length; i++) {
this.status.off(events[i], this.handelChange);
}
}
}
public render(): ReactNode {
return <StatusConsumer>
{(status: Status) => {
this.status = status;
this.mountEvent();
return <C {...this.props} status={status}></C>;
}}
</StatusConsumer>
}
public componentWillUnmount() {
this.unmountEvent();
}
} as any;
}
}
export { export {
Status, StatusContext, useStatus, useStatusWithEvent, Status, StatusContext, useStatus, useStatusWithEvent,

View File

@ -46,7 +46,7 @@ class Label {
* *
*/ */
public equal(label: Label): boolean { public equal(label: Label): boolean {
// if (this.isDeleted() || label.isDeleted()) return false; if (this.isDeleted() || label.isDeleted()) return false;
return this === label || this.id === label.id; return this === label || this.id === label.id;
} }