From 918d2eb6bd34173aba2baf9a6d2bd41ac05fe102 Mon Sep 17 00:00:00 2001 From: Bill Date: Wed, 21 Jul 2021 03:09:03 -0400 Subject: [PATCH] Avatar editor updates --- src/api/nitro/avatar/GetAvatarPalette.ts | 7 + src/api/nitro/avatar/GetAvatarSetType.ts | 7 + src/api/nitro/avatar/index.ts | 2 + src/api/nitro/session/GetClubMemberLevel.ts | 6 + src/api/nitro/session/index.ts | 1 + src/assets/images/avatareditor/clear-icon.png | Bin 263 -> 272 bytes .../images/avatareditor/female-icon.png | Bin 146 -> 236 bytes .../avatareditor/female-selected-icon.png | Bin 196 -> 270 bytes src/assets/images/avatareditor/lg-icon.png | Bin 135 -> 196 bytes .../images/avatareditor/lg-selected-icon.png | Bin 162 -> 236 bytes src/assets/images/avatareditor/male-icon.png | Bin 137 -> 228 bytes .../avatareditor/male-selected-icon.png | Bin 195 -> 256 bytes src/assets/images/avatareditor/sh-icon.png | Bin 122 -> 208 bytes .../images/avatareditor/sh-selected-icon.png | Bin 165 -> 266 bytes src/assets/images/avatareditor/wa-icon.png | Bin 164 -> 257 bytes .../images/avatareditor/wa-selected-icon.png | Bin 199 -> 308 bytes src/assets/styles/icons.scss | 13 +- .../card/content/NitroCardContentView.scss | 2 + src/layout/card/grid/NitroCardGridView.tsx | 4 +- .../card/grid/NitroCardGridView.types.ts | 4 +- .../card/grid/item/NitroCardGridItemView.scss | 3 + src/views/avatar-editor/AvatarEditorView.scss | 61 +++- src/views/avatar-editor/AvatarEditorView.tsx | 260 ++++++++++++------ ...atarEditor.ts => AvatarEditorUtilities.ts} | 175 +++++------- src/views/avatar-editor/common/BodyModel.ts | 9 +- .../avatar-editor/common/CategoryBaseModel.ts | 24 +- src/views/avatar-editor/common/FigureData.ts | 34 ++- .../AvatarEditorFigurePreviewView.tsx | 12 +- .../AvatarEditorFigurePreviewView.types.ts | 4 +- .../AvatarEditorFigureSetItemView.tsx | 3 +- .../views/model/AvatarEditorModelView.tsx | 53 +--- .../model/AvatarEditorModelView.types.ts | 6 +- .../AvatarEditorPaletteSetItem.tsx | 4 +- .../AvatarEditorPaletteSetItem.types.ts | 4 +- .../AvatarEditorPaletteSetView.tsx | 6 +- .../AvatarEditorPaletteSetView.types.ts | 3 +- 36 files changed, 407 insertions(+), 300 deletions(-) create mode 100644 src/api/nitro/avatar/GetAvatarPalette.ts create mode 100644 src/api/nitro/avatar/GetAvatarSetType.ts create mode 100644 src/api/nitro/session/GetClubMemberLevel.ts rename src/views/avatar-editor/common/{AvatarEditor.ts => AvatarEditorUtilities.ts} (62%) diff --git a/src/api/nitro/avatar/GetAvatarPalette.ts b/src/api/nitro/avatar/GetAvatarPalette.ts new file mode 100644 index 00000000..af3526c3 --- /dev/null +++ b/src/api/nitro/avatar/GetAvatarPalette.ts @@ -0,0 +1,7 @@ +import { IPalette } from 'nitro-renderer'; +import { GetAvatarRenderManager } from './GetAvatarRenderManager'; + +export function GetAvatarPalette(paletteId: number): IPalette +{ + return GetAvatarRenderManager().structureData.getPalette(paletteId); +} diff --git a/src/api/nitro/avatar/GetAvatarSetType.ts b/src/api/nitro/avatar/GetAvatarSetType.ts new file mode 100644 index 00000000..ba7c8edd --- /dev/null +++ b/src/api/nitro/avatar/GetAvatarSetType.ts @@ -0,0 +1,7 @@ +import { ISetType } from 'nitro-renderer'; +import { GetAvatarRenderManager } from './GetAvatarRenderManager'; + +export function GetAvatarSetType(setType: string): ISetType +{ + return GetAvatarRenderManager().structureData.getSetType(setType); +} diff --git a/src/api/nitro/avatar/index.ts b/src/api/nitro/avatar/index.ts index 0076857a..258a1ced 100644 --- a/src/api/nitro/avatar/index.ts +++ b/src/api/nitro/avatar/index.ts @@ -1 +1,3 @@ +export * from './GetAvatarPalette'; export * from './GetAvatarRenderManager'; +export * from './GetAvatarSetType'; diff --git a/src/api/nitro/session/GetClubMemberLevel.ts b/src/api/nitro/session/GetClubMemberLevel.ts new file mode 100644 index 00000000..be5e3ffc --- /dev/null +++ b/src/api/nitro/session/GetClubMemberLevel.ts @@ -0,0 +1,6 @@ +import { GetSessionDataManager } from './GetSessionDataManager'; + +export function GetClubMemberLevel(): number +{ + return GetSessionDataManager().clubLevel; +} diff --git a/src/api/nitro/session/index.ts b/src/api/nitro/session/index.ts index ff62191c..31861a96 100644 --- a/src/api/nitro/session/index.ts +++ b/src/api/nitro/session/index.ts @@ -1,6 +1,7 @@ export * from './CanManipulateFurniture'; export * from './GetCanStandUp'; export * from './GetCanUseExpression'; +export * from './GetClubMemberLevel'; export * from './GetFurnitureDataForProductOffer'; export * from './GetFurnitureDataForRoomObject'; export * from './GetOwnPosture'; diff --git a/src/assets/images/avatareditor/clear-icon.png b/src/assets/images/avatareditor/clear-icon.png index 5123270aae46af8eefc40134e4ccf73a84e9222f..e0d50abca8bec826229748f4b83deb79888594af 100644 GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i3?z4Pv7`ej#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6-$0X`wF_4V~f4(;E#ZY5Aa=f>$fAax}{e!>6$|7UQ}TKNUY=PdAuEM{Qf zI}E~%$MaXD00nD3T^vI+f@9BK6l*ZxU<%0o|Ns0=2i97NzT1(7&)+!8`k!-~vZ3`& zMqB7q&NAW6c~&mnS{@mb4_%jPsh2$%&9G zmoNLZE=rwryL_l@|E*lxWQo}PtW$!Y%=830gu&C* K&t;ucLK6Vke`HAj literal 263 zcmV+i0r>ujP)+|00cT90wmV(pW#0caAYzta>z(5Sa7hBgOkmJV}Ziq zHhxaE7>U3|4qaTbN=rHf7ai@EbM(8@vGK86tGs)hj^sv_)9rfxt5|MsT;?;Gt#Db6 urLdaMWZuR}F_9nB0vEd$ue)+0AmhY5quFvir=~o=yhN!#NK{II!5RRn7BcGq diff --git a/src/assets/images/avatareditor/female-selected-icon.png b/src/assets/images/avatareditor/female-selected-icon.png index bfddd6b217f140e98f910bdcd11cf60453156a3a..50ffde0999e1a120ebe110feede7c6606c511e23 100644 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9d!3-qbJ3`31=5EbxddW?978mMmrn2&YB1n%zIgBdxk=Nn_{Z)rI44jetFe?#Ys#DeX`_&g z4U5~{L=`$iJEB^@vM=m3p6{r}+&bg0i+A;$m9`Hp!|m70ukz7Yld6=G_R)Ltfo#i7 zZT+IBVqL6i9cMYTZjXzyExt2B-)HUN-2wk<7u$p;_b|`aWIpWb+{zAg27{-opUXO@ GgeCy3+F73f literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRu!3HEP{;XRGq`Ey_978O6?*=>aH7M}B=J@~r zQ;(X&8d;ymjXR{HuZzAob63$xjZs2fYwlvVb@N@GI&PK;vAoE7I`vH5wxVq1&dGNQ zS<|K+SnzC3!WA9Ei=vk{$~hk67WeV|^L>TbFNcX9kDj@3&oSd--s^ab*<2?-S$j|1 w^A3%W@676}%x6?SxSboq^^0@$f2IcBsRyNO#s3)Z0XmDp)78&qol`;+0A1fpE&u=k diff --git a/src/assets/images/avatareditor/lg-icon.png b/src/assets/images/avatareditor/lg-icon.png index aa9782f68bf5c01a4405cfdf27f370cee9021829..0bdd750e4ec304e7725bcef1891d2957e09f4d77 100644 GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv-!3-oLy1%&rDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheYymzYuB%tC1~R=BGZKLmQ%R6t@PCG<+YP*cJkA1-$YKTtzQZ8Qcszea z3Q*9})5S4FBRDxBCB=c&fl#~JO0!)j<&Nw|?%yjAKhD{IF iNiroFFeDorFfbf?$;hl_Ccq6egu&C*&t;ucLK6Unk}_KW literal 135 zcmZ?wbhEHb6lM@%C}&_${K>+|00cT90wmV(pW#0caKte%GH^I-Sa7hJiCv3FVS?h} zRsl{v9gDz4uAQ9HX=gkPA0BR(vb8#5G4b)yUX8#>J~N9{PxtCcAJbVGw9spUOzxp0 iF9VmKoMz|B^i;Dr!+ViHzEo(G@Jq)Qe{MDw25SJZ=q*YB diff --git a/src/assets/images/avatareditor/lg-selected-icon.png b/src/assets/images/avatareditor/lg-selected-icon.png index d2dfdc72d93b6c8bf575010aba023e32fdc6e25d..7a2853b0272603ea329037f4fbe060b4b8ab4ca9 100644 GIT binary patch delta 219 zcmZ3)_=a(UWIZzj14BgjH#Z=~SRCZ;#IWw1%u67LCEd~2k%3`jKlh(RRv@20z$e5N zNJsT-FpI4U+7%83X4!THj-5a9 zfd-N6x0m3S{tsJi_Y+LgfgM-@lRo59W_|(U&lfKxy7e~z015yANkvXXu0mjfR9`*8 diff --git a/src/assets/images/avatareditor/male-icon.png b/src/assets/images/avatareditor/male-icon.png index aeca1540a347f96eb2114e603d8a97f26786755e..95a1b35267aeeba204ae4c2076fe2c26a0daa767 100644 GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{3?%2B3|#`G7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%xu3o(w$n;jsNCZ+$B|(0{{~4ZcH}C@TI14-?iy0XB4ude`@%$Aj zK*2~)7sn8d;I)0;d<=>l&JX`h5BtrSbnLE) literal 137 zcmZ?wbhEHb6lD-)C}&_${K>+|00cT90wmV(pW#0ca3nA=a>#fTBs4U0@QcM{Y)D{e z6OcD6nGvw)NGFqMP)x-~r6X-(_EszlE+~7pC>u{wd9hLT^mNV8Q!ytuD7#HIFTQrg kbF%XJc@mAgc(OKWc+K#ze>7)ju%=(HlE2y?2>}Lc02cNyI{*Lx diff --git a/src/assets/images/avatareditor/male-selected-icon.png b/src/assets/images/avatareditor/male-selected-icon.png index 3b437c7be92a1fa8c6f0a786806adcad25c1c05c..85debbb3ef2634ce46e8790558cc1c98c4b66ff9 100644 GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{3?%2B3|#`G7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`211o(uw0_jCh{s--N4Pah(T>d>cMXHD{tH>YCql~P|BA!Aznz{IpcBNkeQjEnx?oJHr&dIz4iKRRGIx;Y9 z?C1WI$O`1M1^9%xu3o(w$n;jsNCZ+$B|(0{{~4ZcH}C@TI14-?iy0XB4ude`@%$Aj zKtWee7sn8d;HiC#Tnq|4OxOS0-(6BNRj@=ypmcGDlA3DE>72lh`(jh0+_(K-6eapZ vT6tR7A(?xdS=l!io9=M@Gi@!Sv9i^fe+(Z@mIyBd8pz=3>gTe~DWM4fPHa9M literal 122 zcmZ?wbhEHbRAt~|C}&_${K>+|00cT90wmV(pW#0ca0D_ia>#fXG#qSZV^nbQ*s$<$ z8>5U{568!aN4rEd#rB*CeC*cG>}VIG5%j>NTg7nNpA&%#Pfjqf-ZkZCk(ES#>oZ-YXIyeEZ_hD diff --git a/src/assets/images/avatareditor/sh-selected-icon.png b/src/assets/images/avatareditor/sh-selected-icon.png index 3bdb60521e1249dc9433de433ebd1ed594035043..12c6deb1fb8d7e519e7cb0a09125ddaf7d5b599e 100644 GIT binary patch delta 251 zcmZ3=*u^wKyq=4LnSp_UWmozoAjMc5tq4(EAG;tGVOo@moH!b|NlRbvGPTcD3D?=3GxdDihu;AyqVpALYxI2k;M!Qe1}1p z@p%4<6rf(iwCZ{~8REtBz#uFEJ6nmoZvak^_ppzsf?zrmbhMwWH0 oifeD=WTX}?TJrU9{bz=n##1cQk{I0<0PSV)boFyt=akR{078ITk^lez delta 150 zcmV;H0BQe<0;K_v7k>)~1^@s6_&7vG0001NNklT^L=PBxb^rhX07*qoM6N<$ Ef+5B_oB#j- diff --git a/src/assets/images/avatareditor/wa-icon.png b/src/assets/images/avatareditor/wa-icon.png index 75dffe5b19458c9550ffbb7ef0dd899c6407aea6..8a73b7aef1f23cf4bf38945bd95d23a2e693d349 100644 GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^DnKm6!3-o>{`N=#DaPU;cPEB*=VV@j#L^vo9T^xl z_H+M9WCils0(?STSFc_TWO^%RBmya>k|4j}{|ryJ8+ZYEoCO|{#S9F5he4R}c>anM zpkSG&i(`mJaBCl@P=f&n^XdQgy3#AA-AbOj(zD}An(M^i(-9OP8^mo;s1Kd-zq+|00cT90wmV(pW#0ca8xrea>#gWSa5)WgIOZx#07;z z%`Bp3b0Pv3y0(jGtKH!UOghr5VC$4q5%|b;60@tG&drIBPBx3#PV?b#cuak2BIoJ9&dd{`N=#DaPU;cPEB*=VV@j#L^vo9T^xl z_H+M9WCf`V@Ck7R(x0X<{6E96CfmNuQya+jSNJLhq}WP={DS|30K?|}OZEdrI14-? ziy0XB4ude`@%$AjK*5=wE{-7@!L1Xy`Hm=Xux@eld}4^Obi#s&9Wi)$%zz_d0f0|L)3Cpd%SPUHx3vIVCg!0KTJfaR2}S literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^N9Z=x7a`FHF zP0fxQJJ;FtzMa?d=-n1?F+ndUVFRafmiO6#tGQQf?hy2Em}}LtO`#=e>U*R6>XS?l zW|-~z_OPY5w@Q79f@NCY zI>h=uZ7^$Elp+|WyM@OsVn0t7`~Sz+1uk+*|C7{m+jC3?=rRURS3j3^P6 = props => { - const { columns = 5, theme = NitroCardGridThemes.THEME_DEFAULT, children = null } = props; + const { columns = 5, theme = NitroCardGridThemes.THEME_DEFAULT, className = '', children = null, ...rest } = props; return ( -
+
{ children }
diff --git a/src/layout/card/grid/NitroCardGridView.types.ts b/src/layout/card/grid/NitroCardGridView.types.ts index 58c052ac..f3cc6c80 100644 --- a/src/layout/card/grid/NitroCardGridView.types.ts +++ b/src/layout/card/grid/NitroCardGridView.types.ts @@ -1,4 +1,6 @@ -export interface NitroCardGridViewProps +import { DetailsHTMLAttributes } from 'react'; + +export interface NitroCardGridViewProps extends DetailsHTMLAttributes { columns?: number; theme?: string; diff --git a/src/layout/card/grid/item/NitroCardGridItemView.scss b/src/layout/card/grid/item/NitroCardGridItemView.scss index 19f6c716..69de83c1 100644 --- a/src/layout/card/grid/item/NitroCardGridItemView.scss +++ b/src/layout/card/grid/item/NitroCardGridItemView.scss @@ -3,6 +3,9 @@ max-height: 50px; .grid-item { + display: flex; + justify-content: center; + align-items: center; position: relative; width: 100%; height: 100%; diff --git a/src/views/avatar-editor/AvatarEditorView.scss b/src/views/avatar-editor/AvatarEditorView.scss index d94a3cdc..aaef735d 100644 --- a/src/views/avatar-editor/AvatarEditorView.scss +++ b/src/views/avatar-editor/AvatarEditorView.scss @@ -1,9 +1,13 @@ .nitro-avatar-editor { - width: 600px; + width: 620px; .content-area { - height: 330px; - max-height: 330px; + min-height: 300px; + height: 300px; + } + + .category-item { + height: 40px; } .figure-preview-container { @@ -13,27 +17,53 @@ overflow: hidden; z-index: 1; - .avatar-image { - margin: 45px auto 0; - z-index: 2; - } - .arrow-container { position: absolute; width: 100%; margin: 0 auto; + padding: 0 10px; display: flex; - justify-content: center; + justify-content: space-between; bottom: 12px; - z-index: 3; + z-index: 5; .icon { cursor: pointer; } - - .arrow-left-icon { - margin-right: 10px; - } + } + + .avatar-image { + position: absolute; + left: 0; + right: 0; + bottom: 50px; + margin: 0 auto; + z-index: 4; + } + + .avatar-spotlight { + position: absolute; + top: -10px; + width: 100%; + height: 305px; + margin: 0 auto; + background: transparent url('../../assets/images/avatareditor/spotlight.png') no-repeat center; + opacity: 0.3; + pointer-events: none; + z-index: 3; + } + + .avatar-shadow { + position: absolute; + left: 0; + right: 0; + bottom: 15px; + width: 70px; + height: 30px; + margin: 0 auto; + border-radius: 100%; + background-color: rgba(0, 0, 0, 0.20); + z-index: 2; } &:after { @@ -44,7 +74,8 @@ left: 0; right: 0; border-radius: 50%; - background-color: red; + background-color: $pale-sky; + box-shadow: 0 0 8px 2px rgba($white,.6); transform: scale(2); } } diff --git a/src/views/avatar-editor/AvatarEditorView.tsx b/src/views/avatar-editor/AvatarEditorView.tsx index b8d5a07d..1695ad15 100644 --- a/src/views/avatar-editor/AvatarEditorView.tsx +++ b/src/views/avatar-editor/AvatarEditorView.tsx @@ -1,103 +1,91 @@ -import { AvatarEditorFigureCategory } from 'nitro-renderer'; -import { FC, useCallback, useEffect, useReducer, useState } from 'react'; +import { AvatarDirectionAngle, AvatarEditorFigureCategory, UserFigureComposer } from 'nitro-renderer'; +import { FC, useCallback, useEffect, useState } from 'react'; import { GetSessionDataManager } from '../../api'; import { AvatarEditorEvent } from '../../events/avatar-editor'; +import { SendMessageHook } from '../../hooks'; import { useUiEvent } from '../../hooks/events/ui/ui-event'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../layout'; import { LocalizeText } from '../../utils/LocalizeText'; import { AvatarEditorViewProps } from './AvatarEditorView.types'; -import { AvatarEditor } from './common/AvatarEditor'; +import { AvatarEditorUtilities } from './common/AvatarEditorUtilities'; import { BodyModel } from './common/BodyModel'; import { FigureData } from './common/FigureData'; import { HeadModel } from './common/HeadModel'; import { IAvatarEditorCategoryModel } from './common/IAvatarEditorCategoryModel'; import { LegModel } from './common/LegModel'; import { TorsoModel } from './common/TorsoModel'; -import { AvatarEditorContextProvider } from './context/AvatarEditorContext'; -import { AvatarEditorReducer, initialAvatarEditor } from './reducers/AvatarEditorReducer'; +import { AvatarEditorFigurePreviewView } from './views/figure-preview/AvatarEditorFigurePreviewView'; import { AvatarEditorModelView } from './views/model/AvatarEditorModelView'; +const DEFAULT_MALE_FIGURE: string = 'hr-100.hd-180-7.ch-215-66.lg-270-79.sh-305-62.ha-1002-70.wa-2007'; +const DEFAULT_FEMALE_FIGURE: string = 'hr-515-33.hd-600-1.ch-635-70.lg-716-66-62.sh-735-68'; + export const AvatarEditorView: FC = props => { const [ isVisible, setIsVisible ] = useState(false); - const [ avatarEditorState, dispatchAvatarEditorState ] = useReducer(AvatarEditorReducer, initialAvatarEditor); - const [ avatarEditor, setAvatarEditor ] = useState(null); + const [ figures, setFigures ] = useState>(null); + const [ figureData, setFigureData ] = useState(null); const [ categories, setCategories ] = useState>(null); const [ activeCategory, setActiveCategory ] = useState(null); + const [ lastFigure, setLastFigure ] = useState(null); + const [ lastGender, setLastGender ] = useState(null); + const [ needsReset, setNeedsReset ] = useState(false); const [ isInitalized, setIsInitalized ] = useState(false); const selectCategory = useCallback((name: string) => { + if(!categories) return; + setActiveCategory(categories.get(name)); }, [ categories ]); - const resetCategories = useCallback((editor: AvatarEditor) => + const resetCategories = useCallback(() => { const categories = new Map(); - categories.set(AvatarEditorFigureCategory.GENERIC, new BodyModel(editor)); - categories.set(AvatarEditorFigureCategory.HEAD, new HeadModel(editor)); - categories.set(AvatarEditorFigureCategory.TORSO, new TorsoModel(editor)); - categories.set(AvatarEditorFigureCategory.LEGS, new LegModel(editor)); + categories.set(AvatarEditorFigureCategory.GENERIC, new BodyModel()); + categories.set(AvatarEditorFigureCategory.HEAD, new HeadModel()); + categories.set(AvatarEditorFigureCategory.TORSO, new TorsoModel()); + categories.set(AvatarEditorFigureCategory.LEGS, new LegModel()); setCategories(categories); - setActiveCategory(categories.get(AvatarEditorFigureCategory.GENERIC)); }, []); - const selectGender = useCallback((gender: string) => + const setupFigures = useCallback(() => { - if(gender === avatarEditor.gender) return; - - avatarEditor.gender = gender; + const figures: Map = new Map(); - resetCategories(avatarEditor); - }, [ avatarEditor, resetCategories ]); + const maleFigure = new FigureData(); + const femaleFigure = new FigureData(); + + maleFigure.loadAvatarData(DEFAULT_MALE_FIGURE, FigureData.MALE); + femaleFigure.loadAvatarData(DEFAULT_FEMALE_FIGURE, FigureData.FEMALE); + + figures.set(FigureData.MALE, maleFigure); + figures.set(FigureData.FEMALE, femaleFigure); + + setFigures(figures); + setFigureData(figures.get(FigureData.MALE)); + }, []); const loadAvatarInEditor = useCallback((figure: string, gender: string, reset: boolean = true) => { - if(!avatarEditor) return; - - switch(gender) + gender = AvatarEditorUtilities.getGender(gender); + + let newFigureData = figureData; + + if(gender !== newFigureData.gender) newFigureData = figures.get(gender); + + if(figure !== newFigureData.getFigureString()) newFigureData.loadAvatarData(figure, gender); + + if(newFigureData !== figureData) setFigureData(newFigureData); + + if(reset) { - case FigureData.MALE: - case 'm': - case 'M': - gender = FigureData.MALE; - break; - case FigureData.FEMALE: - case 'f': - case 'F': - gender = FigureData.FEMALE; - break; - default: - gender = FigureData.MALE; + setLastFigure(figureData.getFigureString()); + setLastGender(figureData.gender); } - - let update = false; - - if(gender !== avatarEditor.gender) - { - avatarEditor.gender = gender; - - update = true; - } - - const figureData = avatarEditor.figureData; - - if(!figureData) return; - - if(figure !== figureData.getFigureString()) - { - update = true; - } - - figureData.loadAvatarData(figure, gender); - - if(update) - { - resetCategories(avatarEditor); - } - }, [ avatarEditor, resetCategories ]); + }, [ figures, figureData ]); const onAvatarEditorEvent = useCallback((event: AvatarEditorEvent) => { @@ -105,12 +93,20 @@ export const AvatarEditorView: FC = props => { case AvatarEditorEvent.SHOW_EDITOR: setIsVisible(true); + setNeedsReset(true); return; case AvatarEditorEvent.HIDE_EDITOR: setIsVisible(false); return; case AvatarEditorEvent.TOGGLE_EDITOR: - setIsVisible(prevValue => !prevValue); + setIsVisible(prevValue => + { + const flag = !prevValue; + + if(flag) setNeedsReset(true); + + return flag; + }); return; } }, []); @@ -119,42 +115,130 @@ export const AvatarEditorView: FC = props => useUiEvent(AvatarEditorEvent.HIDE_EDITOR, onAvatarEditorEvent); useUiEvent(AvatarEditorEvent.TOGGLE_EDITOR, onAvatarEditorEvent); - useEffect(() => + const clearFigure = useCallback(() => { - if(!isVisible || isInitalized) return; + loadAvatarInEditor(figureData.getFigureStringWithFace(0, false), figureData.gender, false); + resetCategories(); + }, [ figureData, loadAvatarInEditor, resetCategories ]); - const newEditor = new AvatarEditor(); + const resetFigure = useCallback(() => + { + loadAvatarInEditor(lastFigure, lastGender); + resetCategories(); + }, [ lastFigure, lastGender, loadAvatarInEditor, resetCategories ]); - setAvatarEditor(newEditor); - setIsInitalized(true); - }, [ isVisible, isInitalized ]); + const rotateFigure = useCallback((direction: number) => + { + if(direction < AvatarDirectionAngle.MIN_DIRECTION) + { + direction = (AvatarDirectionAngle.MAX_DIRECTION + (direction + 1)); + } + + if(direction > AvatarDirectionAngle.MAX_DIRECTION) + { + direction = (direction - (AvatarDirectionAngle.MAX_DIRECTION + 1)); + } + + figureData.direction = direction; + }, [ figureData ]); + + const saveFigure = useCallback(() => + { + SendMessageHook(new UserFigureComposer(figureData.gender, figureData.getFigureString())); + }, [ figureData ]); + + const setGender = useCallback((gender: string) => + { + gender = AvatarEditorUtilities.getGender(gender); + + setFigureData(figures.get(gender)); + }, [ figures ]); useEffect(() => { - if(!isVisible || !avatarEditor) return; + if(!categories) return; + + selectCategory(AvatarEditorFigureCategory.GENERIC); + }, [ categories, selectCategory ]); + + useEffect(() => + { + if(!figureData) return; + + AvatarEditorUtilities.CURRENT_FIGURE = figureData; + + resetCategories(); + + return () => AvatarEditorUtilities.CURRENT_FIGURE = null; + }, [ figureData, resetCategories ]); + + useEffect(() => + { + if(!isVisible) return; + + if(!figures) + { + setupFigures(); + + setIsInitalized(true); + + return; + } + }, [ isVisible, figures, setupFigures ]); + + useEffect(() => + { + if(!isVisible || !isInitalized || !needsReset) return; loadAvatarInEditor(GetSessionDataManager().figure, GetSessionDataManager().gender); - }, [ isVisible, avatarEditor, loadAvatarInEditor ]); + setNeedsReset(false); + }, [ isVisible, isInitalized, needsReset, loadAvatarInEditor ]); + + if(!isVisible) return null; return ( - - { isVisible && - - setIsVisible(false) } /> - - { categories && (categories.size > 0) && Array.from(categories.keys()).map(category => - { - return ( - selectCategory(category) }> - { LocalizeText(`avatareditor.category.${ category }`) } - - ); - })} - - - { activeCategory && } - - } - + + setIsVisible(false) } /> + + { categories && (categories.size > 0) && activeCategory && Array.from(categories.keys()).map(category => + { + return ( + selectCategory(category) }> + { LocalizeText(`avatareditor.category.${ category }`) } + + ); + })} + + +
+
+ { activeCategory && } +
+
+ { figureData && +
+ +
+
+
+ rotateFigure(figureData.direction + 1) } /> + rotateFigure(figureData.direction - 1) } /> +
+
} +
+
+ + +
+ +
+
+
+ + ); } diff --git a/src/views/avatar-editor/common/AvatarEditor.ts b/src/views/avatar-editor/common/AvatarEditorUtilities.ts similarity index 62% rename from src/views/avatar-editor/common/AvatarEditor.ts rename to src/views/avatar-editor/common/AvatarEditorUtilities.ts index 3ba88477..eb8b9d25 100644 --- a/src/views/avatar-editor/common/AvatarEditor.ts +++ b/src/views/avatar-editor/common/AvatarEditorUtilities.ts @@ -1,88 +1,79 @@ -import { IPalette, IPartColor, ISetType, IStructureData } from 'nitro-renderer'; -import { GetAvatarRenderManager, GetConfiguration, GetSessionDataManager } from '../../../api'; +import { IPartColor } from 'nitro-renderer'; +import { GetAvatarPalette, GetAvatarRenderManager, GetAvatarSetType, GetClubMemberLevel, GetConfiguration } from '../../../api'; import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem'; import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem'; import { CategoryBaseModel } from './CategoryBaseModel'; import { CategoryData } from './CategoryData'; import { FigureData } from './FigureData'; -const MAX_PALETTES: number = 2; -const DEFAULT_MALE_FIGURE: string = 'hr-100.hd-180-7.ch-215-66.lg-270-79.sh-305-62.ha-1002-70.wa-2007'; -const DEFAULT_FEMALE_FIGURE: string = 'hr-515-33.hd-600-1.ch-635-70.lg-716-66-62.sh-735-68'; - -export class AvatarEditor +export class AvatarEditorUtilities { - private _figureStructureData: IStructureData = GetAvatarRenderManager().structureData; - private _figures: Map = new Map(); - private _gender: string = FigureData.MALE; - private _notifier: () => void = null; + private static MAX_PALETTES: number = 2; - constructor() + public static CURRENT_FIGURE: FigureData = null; + + public static getGender(gender: string): string { - const maleFigure = new FigureData(); - const femaleFigure = new FigureData(); + switch(gender) + { + case FigureData.MALE: + case 'm': + case 'M': + gender = FigureData.MALE; + break; + case FigureData.FEMALE: + case 'f': + case 'F': + gender = FigureData.FEMALE; + break; + default: + gender = FigureData.MALE; + } - maleFigure.loadAvatarData(DEFAULT_MALE_FIGURE, FigureData.MALE); - femaleFigure.loadAvatarData(DEFAULT_FEMALE_FIGURE, FigureData.FEMALE); - - this._figures.set(FigureData.MALE, maleFigure); - this._figures.set(FigureData.FEMALE, femaleFigure); + return gender; } - public getSetType(setType: string): ISetType + public static createCategory(model: CategoryBaseModel, name: string): CategoryData { - if(!this._figureStructureData) return null; - - return this._figureStructureData.getSetType(setType); - } - - public getPalette(paletteId: number): IPalette - { - if(!this._figureStructureData) return null; - - return this._figureStructureData.getPalette(paletteId); - } - - public createCategory(model: CategoryBaseModel, name: string): CategoryData - { - if(!model || !name) return null; + if(!model || !name || !this.CURRENT_FIGURE) return null; const partItems: AvatarEditorGridPartItem[] = []; const colorItems: AvatarEditorGridColorItem[][] = []; let i = 0; - while(i < MAX_PALETTES) + while(i < this.MAX_PALETTES) { colorItems.push([]); i++; } - const setType = this.getSetType(name); + const setType = GetAvatarSetType(name); if(!setType) return null; - const palette = this.getPalette(setType.paletteID); + const palette = GetAvatarPalette(setType.paletteID); if(!palette) return null; - let colorIds = this.figureData.getColourIds(name); + let colorIds = this.CURRENT_FIGURE.getColorIds(name); if(!colorIds) colorIds = []; const partColors: IPartColor[] = new Array(colorIds.length); const clubItemsDimmed = this.clubItemsDimmed; + const clubMemberLevel = GetClubMemberLevel(); for(const partColor of palette.colors.values()) { - if(partColor.isSelectable && (clubItemsDimmed || (this.clubMemberLevel >= partColor.clubLevel))) + if(partColor.isSelectable && (clubItemsDimmed || (clubMemberLevel >= partColor.clubLevel))) { let i = 0; - while(i < MAX_PALETTES) + while(i < this.MAX_PALETTES) { - const isDisabled = (this.clubMemberLevel < partColor.clubLevel); + const isDisabled = (clubMemberLevel < partColor.clubLevel); const colorItem = new AvatarEditorGridColorItem(partColor, isDisabled); colorItems[i].push(colorItem); @@ -108,11 +99,11 @@ export class AvatarEditor if(clubItemsDimmed) { - mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this._gender, 2); + mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, 2); } else { - mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this._gender, this.clubMemberLevel); + mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, clubMemberLevel); } const isntMandatorySet = (mandatorySetIds.indexOf(name) === -1); @@ -142,17 +133,15 @@ export class AvatarEditor { isValidGender = true; } - else + + else if(partSet.gender === this.CURRENT_FIGURE.gender) { - if(partSet.gender === this._gender) - { - isValidGender = true; - } + isValidGender = true; } - if(partSet.isSelectable && isValidGender && (clubItemsDimmed || (this.clubMemberLevel >= partSet.clubLevel))) + if(partSet.isSelectable && isValidGender && (clubItemsDimmed || (clubMemberLevel >= partSet.clubLevel))) { - const isDisabled = (this.clubMemberLevel < partSet.clubLevel); + const isDisabled = (clubMemberLevel < partSet.clubLevel); let isValid = true; @@ -186,7 +175,7 @@ export class AvatarEditor i = 0; - while(i < MAX_PALETTES) + while(i < this.MAX_PALETTES) { colorItems[i].sort(this.colorSorter); @@ -196,7 +185,7 @@ export class AvatarEditor return new CategoryData(name, partItems, colorItems); } - private clubSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number + public static clubSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number { const clubLevelA = (!a.partSet ? 9999999999 : a.partSet.clubLevel); const clubLevelB = (!b.partSet ? 9999999999 : b.partSet.clubLevel); @@ -218,7 +207,23 @@ export class AvatarEditor return 0; } - private noobSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number + public static colorSorter(a: AvatarEditorGridColorItem, b: AvatarEditorGridColorItem): number + { + const clubLevelA = (!a.partColor ? -1 : a.partColor.clubLevel); + const clubLevelB = (!b.partColor ? -1 : b.partColor.clubLevel); + + if(clubLevelA < clubLevelB) return -1; + + if(clubLevelA > clubLevelB) return 1; + + if(a.partColor.index < b.partColor.index) return -1; + + if(a.partColor.index > b.partColor.index) return 1; + + return 0; + } + + public static noobSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number { const clubLevelA = (!a.partSet ? -1 : a.partSet.clubLevel); const clubLevelB = (!b.partSet ? -1 : b.partSet.clubLevel); @@ -240,67 +245,33 @@ export class AvatarEditor return 0; } - private colorSorter(a: AvatarEditorGridColorItem, b: AvatarEditorGridColorItem): number + public static avatarSetFirstSelectableColor(name: string): number { - const clubLevelA = (!a.partColor ? -1 : a.partColor.clubLevel); - const clubLevelB = (!b.partColor ? -1 : b.partColor.clubLevel); + const setType = GetAvatarSetType(name); - if(clubLevelA < clubLevelB) return -1; + if(!setType) return -1; - if(clubLevelA > clubLevelB) return 1; + const palette = GetAvatarPalette(setType.paletteID); - if(a.partColor.index < b.partColor.index) return -1; + if(!palette) return -1; - if(a.partColor.index > b.partColor.index) return 1; + for(const color of palette.colors.values()) + { + if(!color.isSelectable || (GetClubMemberLevel() < color.clubLevel)) continue; - return 0; + return color.id; + } + + return -1; } - public get clubMemberLevel(): number - { - return GetSessionDataManager().clubLevel; - } - - private get clubItemsFirst(): boolean + public static get clubItemsFirst(): boolean { return GetConfiguration('avatareditor.show.clubitems.first', true); } - private get clubItemsDimmed(): boolean + public static get clubItemsDimmed(): boolean { return GetConfiguration('avatareditor.show.clubitems.dimmed', true); } - - public get figureData(): FigureData - { - return this._figures.get(this._gender); - } - - public get gender(): string - { - return this._gender; - } - - public set gender(gender: string) - { - if(this._gender === gender) return; - - this._gender = gender; - - if(this.figureData) this.figureData.notify = this.notify; - - if(this.notify) this.notify(); - } - - public get notify(): () => void - { - return this._notifier; - } - - public set notify(notifier: () => void) - { - if(this.figureData) this.figureData.notify = notifier; - - this._notifier = notifier; - } } diff --git a/src/views/avatar-editor/common/BodyModel.ts b/src/views/avatar-editor/common/BodyModel.ts index 41971d51..02151180 100644 --- a/src/views/avatar-editor/common/BodyModel.ts +++ b/src/views/avatar-editor/common/BodyModel.ts @@ -1,5 +1,6 @@ import { AvatarEditorFigureCategory, AvatarScaleType, AvatarSetType, IAvatarImageListener } from 'nitro-renderer'; import { GetAvatarRenderManager } from '../../../api'; +import { AvatarEditorUtilities } from './AvatarEditorUtilities'; import { CategoryBaseModel } from './CategoryBaseModel'; import { FigureData } from './FigureData'; @@ -25,15 +26,15 @@ export class BodyModel extends CategoryBaseModel implements IAvatarImageListener protected updateSelectionsFromFigure(name: string): void { - if(!this._categories || !this._editor || !this._editor.figureData) return; + if(!this._categories || !AvatarEditorUtilities.CURRENT_FIGURE) return; const category = this._categories.get(name); if(!category) return; - const setId = this._editor.figureData.getPartSetId(name); + const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(name); - let colorIds = this._editor.figureData.getColourIds(name); + let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(name); if(!colorIds) colorIds = []; @@ -42,7 +43,7 @@ export class BodyModel extends CategoryBaseModel implements IAvatarImageListener for(const part of category.parts) { - const figure = this._editor.figureData.getFigureStringWithFace(part.id); + const figure = AvatarEditorUtilities.CURRENT_FIGURE.getFigureStringWithFace(part.id); const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, this); const sprite = avatarImage.getImageAsSprite(AvatarSetType.HEAD); diff --git a/src/views/avatar-editor/common/CategoryBaseModel.ts b/src/views/avatar-editor/common/CategoryBaseModel.ts index 9d1100ee..ab65af72 100644 --- a/src/views/avatar-editor/common/CategoryBaseModel.ts +++ b/src/views/avatar-editor/common/CategoryBaseModel.ts @@ -1,18 +1,16 @@ -import { AvatarEditor } from './AvatarEditor'; +import { AvatarEditorUtilities } from './AvatarEditorUtilities'; import { CategoryData } from './CategoryData'; import { IAvatarEditorCategoryModel } from './IAvatarEditorCategoryModel'; export class CategoryBaseModel implements IAvatarEditorCategoryModel { - protected _editor: AvatarEditor; protected _categories: Map; protected _isInitalized: boolean; protected _maxPaletteCount: number; private _disposed: boolean; - constructor(editor: AvatarEditor) + constructor() { - this._editor = editor; this._isInitalized = false; this._maxPaletteCount = 0; } @@ -51,7 +49,7 @@ export class CategoryBaseModel implements IAvatarEditorCategoryModel if(existing) return; - existing = this._editor.createCategory(this, name); + existing = AvatarEditorUtilities.createCategory(this, name); if(!existing) return; @@ -66,9 +64,9 @@ export class CategoryBaseModel implements IAvatarEditorCategoryModel if(!category) return; - const setId = this._editor.figureData.getPartSetId(figure); + const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(figure); - let colorIds = this._editor.figureData.getColourIds(figure); + let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(figure); if(!colorIds) colorIds = []; @@ -120,9 +118,9 @@ export class CategoryBaseModel implements IAvatarEditorCategoryModel { const partItem = category.getCurrentPart(); - if(partItem && this._editor && this._editor.figureData) + if(partItem && AvatarEditorUtilities.CURRENT_FIGURE) { - this._editor.figureData.savePartData(name, partItem.id, category.getSelectedColorIds(), true); + AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true); } didStrip = true; @@ -148,9 +146,9 @@ export class CategoryBaseModel implements IAvatarEditorCategoryModel { const partItem = category.getCurrentPart(); - if(partItem && this._editor && this._editor.figureData) + if(partItem && AvatarEditorUtilities.CURRENT_FIGURE) { - this._editor.figureData.savePartData(name, partItem.id, category.getSelectedColorIds(), true); + AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true); } didStrip = true; @@ -185,7 +183,7 @@ export class CategoryBaseModel implements IAvatarEditorCategoryModel this._maxPaletteCount = partItem.maxColorIndex; - this._editor.figureData.savePartData(category, partItem.id, categoryData.getSelectedColorIds(), true); + AvatarEditorUtilities.CURRENT_FIGURE.savePartData(category, partItem.id, categoryData.getSelectedColorIds(), true); } public selectColor(category: string, colorIndex: number, paletteId: number): void @@ -209,7 +207,7 @@ export class CategoryBaseModel implements IAvatarEditorCategoryModel return; } - this._editor.figureData.savePartSetColourId(category, categoryData.getSelectedColorIds(), true); + AvatarEditorUtilities.CURRENT_FIGURE.savePartSetColourId(category, categoryData.getSelectedColorIds(), true); } public getCategoryData(category: string): CategoryData diff --git a/src/views/avatar-editor/common/FigureData.ts b/src/views/avatar-editor/common/FigureData.ts index 2e447cb3..d186b4c0 100644 --- a/src/views/avatar-editor/common/FigureData.ts +++ b/src/views/avatar-editor/common/FigureData.ts @@ -1,5 +1,9 @@ -export class FigureData +import { AvatarEditorUtilities } from './AvatarEditorUtilities'; + +export class FigureData { + private static DEFAULT_DIRECTION: number = 4; + public static MALE: string = 'M'; public static FEMALE: string = 'F'; public static UNISEX: string = 'U'; @@ -24,6 +28,7 @@ private _data: Map; private _colors: Map; private _gender: string = 'M'; + private _direction: number = FigureData.DEFAULT_DIRECTION; private _avatarEffectType: number = -1; private _notifier: () => void = null; @@ -80,14 +85,13 @@ return -1; } - public getColourIds(colorId: string): number[] + public getColorIds(setType: string): number[] { - const existing = this._colors.get(colorId); + const existing = this._colors.get(setType); if(existing !== undefined) return existing; - return []; - // return [this._avatarEditor._Str_24919(k)]; + return [ AvatarEditorUtilities.avatarSetFirstSelectableColor(setType) ]; } public getFigureString(): string @@ -167,9 +171,9 @@ if(_arg_3) this.updateView(); } - public savePartSetColourId(k: string, _arg_2: number[], _arg_3: boolean = true): void + public savePartSetColourId(setType: string, colorIds: number[], update: boolean = true): void { - switch(k) + switch(setType) { case FigureData.FACE: case FigureData.HAIR: @@ -184,11 +188,11 @@ case FigureData.TROUSERS: case FigureData.SHOES: case FigureData.TROUSER_ACCESSORIES: - this._colors.set(k, _arg_2); + this._colors.set(setType, colorIds); break; } - if(_arg_3) this.updateView(); + if(update) this.updateView(); } public getFigureStringWithFace(k: number, override = true): string @@ -249,6 +253,18 @@ return this._gender; } + public get direction(): number + { + return this._direction; + } + + public set direction(direction: number) + { + this._direction = direction; + + this.updateView(); + } + public set avatarEffectType(k: number) { this._avatarEffectType = k; diff --git a/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.tsx b/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.tsx index 73e37a69..352f7e58 100644 --- a/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.tsx +++ b/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.tsx @@ -4,7 +4,7 @@ import { AvatarEditorFigurePreviewViewProps } from './AvatarEditorFigurePreviewV export const AvatarEditorFigurePreviewView: FC = props => { - const { editor = null } = props; + const { figureData = null } = props; const [ updateId, setUpdateId ] = useState(-1); const rerender = useCallback(() => @@ -14,15 +14,15 @@ export const AvatarEditorFigurePreviewView: FC { - if(!editor) return; + if(!figureData) return; - editor.notify = rerender; + figureData.notify = rerender; return () => { - editor.notify = null; + figureData.notify = null; } - }, [ editor, rerender ] ); + }, [ figureData, rerender ] ); - return + return } diff --git a/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.types.ts b/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.types.ts index 0bfcf8f9..3956305c 100644 --- a/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.types.ts +++ b/src/views/avatar-editor/views/figure-preview/AvatarEditorFigurePreviewView.types.ts @@ -1,6 +1,6 @@ -import { AvatarEditor } from '../../common/AvatarEditor'; +import { FigureData } from '../../common/FigureData'; export interface AvatarEditorFigurePreviewViewProps { - editor: AvatarEditor; + figureData: FigureData; } diff --git a/src/views/avatar-editor/views/figure-set-item/AvatarEditorFigureSetItemView.tsx b/src/views/avatar-editor/views/figure-set-item/AvatarEditorFigureSetItemView.tsx index ef4c0cc4..09b4e33e 100644 --- a/src/views/avatar-editor/views/figure-set-item/AvatarEditorFigureSetItemView.tsx +++ b/src/views/avatar-editor/views/figure-set-item/AvatarEditorFigureSetItemView.tsx @@ -24,8 +24,9 @@ export const AvatarEditorFigureSetItemView: FC onClick(partItem) }> + onClick(partItem) }> { partItem.isHC && } + { partItem.isClear && } ); } diff --git a/src/views/avatar-editor/views/model/AvatarEditorModelView.tsx b/src/views/avatar-editor/views/model/AvatarEditorModelView.tsx index c842c94e..68e1645b 100644 --- a/src/views/avatar-editor/views/model/AvatarEditorModelView.tsx +++ b/src/views/avatar-editor/views/model/AvatarEditorModelView.tsx @@ -1,17 +1,13 @@ -import { UserFigureComposer } from 'nitro-renderer'; import { FC, useCallback, useEffect, useState } from 'react'; -import { SendMessageHook } from '../../../../hooks'; -import { LocalizeText } from '../../../../utils/LocalizeText'; import { CategoryData } from '../../common/CategoryData'; import { FigureData } from '../../common/FigureData'; -import { AvatarEditorFigurePreviewView } from '../figure-preview/AvatarEditorFigurePreviewView'; import { AvatarEditorFigureSetView } from '../figure-set/AvatarEditorFigureSetView'; import { AvatarEditorPaletteSetView } from '../palette-set/AvatarEditorPaletteSetView'; import { AvatarEditorModelViewProps } from './AvatarEditorModelView.types'; export const AvatarEditorModelView: FC = props => { - const { model = null, editor = null, selectGender = null } = props; + const { model = null, gender = null, setGender = null } = props; const [ activeCategory, setActiveCategory ] = useState(null); const [ maxPaletteCount, setMaxPaletteCount ] = useState(1); @@ -35,13 +31,6 @@ export const AvatarEditorModelView: FC = props => } }, [ model ]); - const saveFigure = useCallback(() => - { - const figureData = editor.figureData; - - SendMessageHook(new UserFigureComposer(figureData.gender, figureData.getFigureString())); - }, [ editor ]); - useEffect(() => { model.init(); @@ -58,49 +47,35 @@ export const AvatarEditorModelView: FC = props => return (
-
+
{ model.canSetGender && <> - selectGender(FigureData.MALE) } /> - selectGender(FigureData.FEMALE) } /> +
setGender(FigureData.MALE) }> + +
+
setGender(FigureData.FEMALE) }> + +
} { !model.canSetGender && model.categories && (model.categories.size > 0) && Array.from(model.categories.keys()).map(name => { const category = model.categories.get(name); return ( - selectCategory(name) } /> +
selectCategory(name) }> + +
); })}
-
+
-
-
- -
- - -
-
-
-
- - -
- -
-
-
+
{ (maxPaletteCount >= 1) && } { (maxPaletteCount === 2) && - } + }
); diff --git a/src/views/avatar-editor/views/model/AvatarEditorModelView.types.ts b/src/views/avatar-editor/views/model/AvatarEditorModelView.types.ts index dc81491a..b86b58aa 100644 --- a/src/views/avatar-editor/views/model/AvatarEditorModelView.types.ts +++ b/src/views/avatar-editor/views/model/AvatarEditorModelView.types.ts @@ -1,9 +1,9 @@ -import { AvatarEditor } from '../../common/AvatarEditor'; +import { Dispatch, SetStateAction } from 'react'; import { IAvatarEditorCategoryModel } from '../../common/IAvatarEditorCategoryModel'; export interface AvatarEditorModelViewProps { model: IAvatarEditorCategoryModel; - editor: AvatarEditor; - selectGender: (gender: string) => void; + gender: string; + setGender: Dispatch>; } diff --git a/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.tsx b/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.tsx index 2dab88d1..1a46b115 100644 --- a/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.tsx +++ b/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.tsx @@ -4,7 +4,7 @@ import { AvatarEditorPaletteSetItemProps } from './AvatarEditorPaletteSetItem.ty export const AvatarEditorPaletteSetItem: FC = props => { - const { colorItem = null, onClick = null } = props; + const { colorItem = null, ...rest } = props; const [ updateId, setUpdateId ] = useState(-1); const rerender = useCallback(() => @@ -22,5 +22,5 @@ export const AvatarEditorPaletteSetItem: FC = p } }) - return onClick(colorItem) } /> + return } diff --git a/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.types.ts b/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.types.ts index 5930f9a4..a0abc62e 100644 --- a/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.types.ts +++ b/src/views/avatar-editor/views/palette-set-item/AvatarEditorPaletteSetItem.types.ts @@ -1,7 +1,7 @@ +import { DetailsHTMLAttributes } from 'react'; import { AvatarEditorGridColorItem } from '../../common/AvatarEditorGridColorItem'; -export interface AvatarEditorPaletteSetItemProps +export interface AvatarEditorPaletteSetItemProps extends DetailsHTMLAttributes { colorItem: AvatarEditorGridColorItem; - onClick: (item: AvatarEditorGridColorItem) => void; } diff --git a/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx b/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx index fc8c4fc9..65c2968f 100644 --- a/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx +++ b/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.tsx @@ -7,7 +7,7 @@ import { AvatarEditorPaletteSetViewProps } from './AvatarEditorPaletteSetView.ty export const AvatarEditorPaletteSetView: FC = props => { - const { model = null, category = null, paletteSet = [], paletteIndex = -1 } = props; + const { model = null, category = null, paletteSet = [], paletteIndex = -1, ...rest } = props; const selectColor = useCallback((item: AvatarEditorGridColorItem) => { @@ -19,10 +19,10 @@ export const AvatarEditorPaletteSetView: FC = p }, [ model, category, paletteSet, paletteIndex ]); return ( - + { (paletteSet.length > 0) && paletteSet.map((item, index) => { - return ; + return selectColor(item) } />; }) } ); diff --git a/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.types.ts b/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.types.ts index 9fa8e2b6..e7e62483 100644 --- a/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.types.ts +++ b/src/views/avatar-editor/views/palette-set/AvatarEditorPaletteSetView.types.ts @@ -1,8 +1,9 @@ +import { DetailsHTMLAttributes } from 'react'; import { AvatarEditorGridColorItem } from '../../common/AvatarEditorGridColorItem'; import { CategoryData } from '../../common/CategoryData'; import { IAvatarEditorCategoryModel } from '../../common/IAvatarEditorCategoryModel'; -export interface AvatarEditorPaletteSetViewProps +export interface AvatarEditorPaletteSetViewProps extends DetailsHTMLAttributes { model: IAvatarEditorCategoryModel; category: CategoryData;