Skip to content

Commit

Permalink
Save to clone
Browse files Browse the repository at this point in the history
  • Loading branch information
fecapark committed Jun 20, 2022
1 parent 291945f commit 5843b61
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 85 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,7 @@ class RouterComponent extends Component {

## Todo

4. Component render 단위에서 애니메이션 처리가 가능한 프레임워크 제작
1. main-page 라우팅 처리
2. local storage 연결
3. headcard fadeout 애니메이션 만들기
4. main page 디자인 구상해보기
10 changes: 3 additions & 7 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
<!-- <link rel="icon" type="image/svg+xml" href="favicon.svg" /> -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- <link
href="https://hangeul.pstatic.net/hangeul_static/css/nanum-square.css"
rel="stylesheet"
/> -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
Expand All @@ -24,10 +20,10 @@
href="//cdn.jsdelivr.net/npm/font-applesdgothicneo@1.0/all.min.css"
/>
<title>Todo List</title>
<script src="//cdn.jsdelivr.net/npm/eruda"></script>
<!-- <script src="//cdn.jsdelivr.net/npm/eruda"></script>
<script>
eruda.init();
</script>
</script> -->
</head>
<body>
<script type="module" src="/src/main.ts"></script>
Expand Down
64 changes: 46 additions & 18 deletions src/App.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import "./App.scss";
import { ROUTES } from "./core/Router/routes";
import InitialLogo from "./components/InitialLogo/InitialLogo";
import Router from "./core/Router/Router";
import Component from "./core/Component/Component";
import InitialLogo from "./components/InitialLogo/InitialLogo";
import MainContainer from "./components/MainContainer/MainContainer";
import Router from "./core/Router/Router";
import LocalStorageManager from "./core/LocalStorage/localStorageManager";

export default class App extends Component {
appRendered: boolean = false;
initialLogo!: InitialLogo;
mainContainer!: MainContainer;
private appRendered: boolean = false;
private initialLogo!: InitialLogo;
private mainContainer!: MainContainer;

constructor() {
super({ id: "app" });

// States
this.store.setDefaultState("logined", false);
this.store.setDefaultState("logoEnd", false);
this.store.setAction("setLogoEnd", ({ state }) => {
return { logoEnd: !state["logoEnd"] };
Expand All @@ -25,32 +25,65 @@ export default class App extends Component {
ROUTES.setInitialRootPath();
new Router(document.createElement("a")); // Initialize router events

this.initializeLocalStorage();
this.render();
}

setViews() {
private initializeLocalStorage() {
const setDefault = (key: string, value: any) => {
try {
LocalStorageManager.get(key);
} catch (e) {
LocalStorageManager.set(key, value);
}
};

setDefault("logined", false);
}

private setViews() {
ROUTES.setViewTo("#", this.renderHome.bind(this), this.container);
ROUTES.setViewTo("#logo", this.renderLogo.bind(this), this.container);
ROUTES.setViewTo("#signin", this.renderSignIn.bind(this), this.container);
ROUTES.setViewTo("#main", this.renderDummyMain.bind(this), this.container);
}

renderHome() {
private renderHome() {
ROUTES.viewWithRedirect("#logo");
}

renderLogo() {
private renderLogo() {
this.initialLogo = new InitialLogo(() => {
this.store.dispatch("setLogoEnd", {});
});

this.container.appendChild(this.initialLogo.container);
}

renderSignIn() {
this.mainContainer = new MainContainer();
private renderSignIn() {
if (LocalStorageManager.get("logined").parsed) {
ROUTES.viewWithRedirect("#");
return;
}

this.mainContainer = new MainContainer(this.store);
this.container.appendChild(this.mainContainer.container);
}

private renderDummyMain() {
this.container.innerHTML = `
<div>You logined!</div>
<div>
<button>Logout</button>
</div>
`;

this.qs("button")!.addEventListener("pointerup", () => {
LocalStorageManager.set("logined", false);
ROUTES.viewWithRedirect("#signin");
});
}

render() {
document.body.prepend(this.container);

Expand All @@ -61,14 +94,9 @@ export default class App extends Component {
return;
}

// When re-rendered before logo animation ends.
// if (!this.store.getState("logoEnd")) {
// throw Error("Un expected state change.");
// }

// Branch routes for user logined before or else.
if (this.store.getState("logined")) {
this.container.innerHTML = "Welcome! You logined!";
if (LocalStorageManager.get("logined").parsed) {
ROUTES.viewWithRedirect("#main");
} else {
ROUTES.viewWithRedirect("#signin");
}
Expand Down
2 changes: 0 additions & 2 deletions src/components/Buttons/CircleButton/CircleButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ export default class CircleButton extends Component {

this.removeRipple();

console.log("fuck");

this.ripple = document.createElement("div");
this.ripple.classList.add("ripple");

Expand Down
70 changes: 40 additions & 30 deletions src/components/Cards/HeadInfoCard/HeadInfoCard.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import "./HeadInfoCard.scss";
import Component from "../../../core/Component/Component";
import { executeAnimation as resultProfileAnimation } from "./ResultProfileTrigger.ani";
import { executeAnimation as backMaskAnimation } from "./BackMask.ani";
import TagBlock from "../../Tag/TagBlock/TagBlock";
import CircleButton from "../../Buttons/CircleButton/CircleButton";
import { executeAnimation as resultProfileAnimation } from "./ResultProfileTrigger.ani";
import { executeAnimation as backMaskAnimation } from "./BackMask.ani";
import { Store } from "Store-Type";
import LocalStorageManager from "../../../core/LocalStorage/localStorageManager";

interface ResultProfileData {
name: string;
Expand All @@ -20,7 +22,10 @@ export default class HeadInfoCard extends Component {
private isResultProfileAnimationEnd: boolean = false;
private resultProfileData: ResultProfileData = { name: "", tags: [] };

constructor({ reRenderCardContainer }: HandleOptions) {
constructor(
private readonly globalStore: Store.AbstractStore,
{ reRenderCardContainer }: HandleOptions
) {
super({ classNames: ["info-card", "head"] });

this.reRenderCardContainer = reRenderCardContainer;
Expand All @@ -42,6 +47,29 @@ export default class HeadInfoCard extends Component {
this.store.dispatch("triggerResultProfile", { name, tags });
}

private submit() {
// console.log(this.globalStore.getState("logined"));
LocalStorageManager.set("logined", true);
// console.log(LocalStorageManager.get("logined"));
}

private handleBackButton(e: PointerEvent) {
e.stopPropagation();

if (!this.isResultProfileAnimationEnd) return;
if (this.isBackButtonTriggered) return;

this.isBackButtonTriggered = true;

requestAnimationFrame(() => {
backMaskAnimation(
this.container,
this.qs(".i-mask")!,
this.reRenderCardContainer
);
});
}

render() {
if (!this.isResultProfileTriggered) {
this.container.innerHTML = `
Expand Down Expand Up @@ -88,35 +116,17 @@ export default class HeadInfoCard extends Component {

this.appendElementsTo(
".submit-button-wrapper",
new CircleButton(
() => {
// Go!
},
{
content: '<i class="fa-solid fa-check"></i>',
shadowLevel: 2,
hiddenAtStart: true,
}
).container
new CircleButton(this.submit.bind(this), {
content: '<i class="fa-solid fa-check"></i>',
shadowLevel: 2,
hiddenAtStart: true,
}).container
);

const backButton = this.qs(".back-button-wrapper")! as HTMLElement;
backButton.addEventListener("pointerup", (e: PointerEvent) => {
e.stopPropagation();

if (!this.isResultProfileAnimationEnd) return;
if (this.isBackButtonTriggered) return;

this.isBackButtonTriggered = true;

requestAnimationFrame(() => {
backMaskAnimation(
this.container,
this.qs(".i-mask")!,
this.reRenderCardContainer
);
});
});
this.qs(".back-button-wrapper")!.addEventListener(
"pointerup",
this.handleBackButton.bind(this) as EventListener
);

requestAnimationFrame(() => {
resultProfileAnimation(
Expand Down
3 changes: 0 additions & 3 deletions src/components/InitialLogo/InitialLogo.ani.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ function getMaskAnimation(
return masks[idx].getBoundingClientRect();
}

// Sizes
const resultSize = { width: 300, height: 135 };

// Animation parameters
const duration = 0.35;
const deafultDelay = 0.6;
const delayGap = 0.125;
Expand Down
4 changes: 2 additions & 2 deletions src/components/InitialLogo/InitialLogo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
justify-content: center;

#sub-logo-text {
letter-spacing: 2.5px;
letter-spacing: 2px;
font-weight: 500;
font-size: 11px;
font-size: 10px;
text-transform: uppercase;
color: #f0f0f0;
}
Expand Down
11 changes: 6 additions & 5 deletions src/components/MainContainer/MainContainer.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import "./MainContainer.scss";
import Component from "../../core/Component/Component";
import HeadInfoCard from "../Cards/HeadInfoCard/HeadInfoCard";
import InfoCard from "../Cards/InfoCard/InfoCard";
import CircleButton from "../Buttons/CircleButton/CircleButton";
import TextInput from "../Inputs/TextInput/TextInput";
import TagInput from "../Inputs/TagInput/TagInput";
import CircleButton from "../Buttons/CircleButton/CircleButton";
import HeadInfoCard from "../Cards/HeadInfoCard/HeadInfoCard";
import InfoCard from "../Cards/InfoCard/InfoCard";
import { executeAnimation as splitAnimation } from "../Cards/InfoCardSplit.ani";
import { executeAnimation as mergeAnimation } from "../Cards/InfoCardMerge.ani";
import { Store } from "Store-Type";

export default class MainContainer extends Component {
private readonly TITLE_CONTAINER_SELECTOR: string = ".card-title-container";
Expand All @@ -21,7 +22,7 @@ export default class MainContainer extends Component {
private nameInfoValid: boolean = false;
private tagInfoValid: boolean = false;

constructor() {
constructor(private readonly globalStore: Store.AbstractStore) {
super({ id: "main-container" });

this.render();
Expand All @@ -46,7 +47,7 @@ export default class MainContainer extends Component {
}

private renderHeadCard(): HeadInfoCard {
return new HeadInfoCard({
return new HeadInfoCard(this.globalStore, {
reRenderCardContainer: this.render.bind(this),
});
}
Expand Down
29 changes: 29 additions & 0 deletions src/core/LocalStorage/localStorageManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class LSData {
readonly data: string;
readonly parsed: any;

constructor(data: string) {
this.data = data;
this.parsed = this.parse(data);
}

private parse(data: string): any {
return JSON.parse(data);
}
}

export default class LocalStorageManager {
static get(key: string): LSData {
const hashKey: string = key.getHash().hash;

const data: string | null = window.localStorage.getItem(hashKey);

if (!data) throw Error(`Invalid key name '${key}'.`);
return new LSData(data);
}

static set(key: string, data: any) {
const hashKey: string = key.getHash().hash;
return window.localStorage.setItem(hashKey, JSON.stringify(data));
}
}
4 changes: 4 additions & 0 deletions src/core/Router/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export class ROUTES {
name: "signin",
view: defaultView,
},
"#main": {
name: "main",
view: defaultView,
},
};

static setViewTo(
Expand Down
4 changes: 2 additions & 2 deletions src/core/Store/PublishSubscribe.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PubSub } from "Store-Type";
import { PubSub } from "PubSub-Type";

export default class PublishSubscribe {
export default class PublishSubscribe implements PubSub.AbstractPubSub {
private events: PubSub.Events = {};

subscribe(eventType: string, callBack: PubSub.EventHandler): number {
Expand Down
Loading

0 comments on commit 5843b61

Please sign in to comment.