Skip to content

Commit

Permalink
Merge pull request #20 from Appbird/feature/resolve-#16
Browse files Browse the repository at this point in the history
Feature/resolve #16
App#gotoTopメソッドがscrollToThePagePositionに変更され、一部仕様変更あり。名称変更以外は破壊的変更はなし
  • Loading branch information
Appbird authored Sep 3, 2021
2 parents b7b9995 + cfc2785 commit 6a2012e
Show file tree
Hide file tree
Showing 20 changed files with 101 additions and 43 deletions.
27 changes: 22 additions & 5 deletions src/ts/client/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { LoginAdministrator, LoginAdministratorReadOnly } from "./Administrator/
import { IAppUsedToChangeState } from "./interface/AppInterfaces";
import firebase from "firebase/app";
import {PageNotificationAdministrator} from "./Administrator/PageNotificationAdministrator"
import { miliseconds } from "../utility/timeAsyncUtility";
import { fitInRange } from "../utility/numericUtility";
export default class App implements IAppUsedToChangeState{
private _state:StateAdministrator;
private loginAd:LoginAdministrator | null = null;
Expand Down Expand Up @@ -108,7 +110,7 @@ export default class App implements IAppUsedToChangeState{
return this.loginAd;
}
async transition<T extends keyof PageStates>(nextState:T, requestObject:RequiredObjectType<PageStates[T]>,{ifAppendHistory=true,title=""}:{ifAppendHistory?:boolean,title?:string} = {}){
this.goToTop();
this.scrollToThePagePosition();
try {
await this.transitionAd.transition(nextState,requestObject,{title:title})
if (ifAppendHistory) this.historyAd.registerCurrentPage();
Expand Down Expand Up @@ -162,10 +164,25 @@ export default class App implements IAppUsedToChangeState{
acceptTheTerms(){
this.historyAd.clearIntroduction()
}
goToTop(){
var scrolled = ( window.pageYOffset !== undefined ) ? window.pageYOffset: document.documentElement.scrollTop;
window.scrollTo( 0, Math.floor( scrolled / 1.5 ) );
if ( scrolled > 2 ) { window.setTimeout( ()=>this.goToTop(), 30 );}
/**
* ページをスムーズにスクロールします。
* @param YPosition 飛ばすページのY座標の位置。与えられたY座標が上になるまで
*/
async scrollToThePagePosition(YPosition:number = 0){
YPosition = fitInRange(
0,
YPosition,
document.documentElement.scrollHeight - window.innerHeight
)
const distanceAtFirst = window.pageYOffset - YPosition;
let currentDistance = distanceAtFirst
const commonRatio = 2/3
while (true) {
currentDistance = currentDistance * commonRatio
window.scrollTo( 0, currentDistance + YPosition );
if (Math.abs(currentDistance) < 2) break;
await miliseconds(30)
}
}

}
2 changes: 1 addition & 1 deletion src/ts/client/interface/AppInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface IAppUsedToRead{
accessToAPI:<T extends keyof APIFunctions_noChanging>(functionName: T, requiredObj: APIFunctions[T]["atServer"]) => Promise<APIFunctions[T]["atClient"]>
}
export interface IAppUsedToReadAndChangeOnlyPageState/*IAppUsedToReadAndChangeOnlyPageState*/ extends IAppUsedToRead{
goToTop:()=>void;
scrollToThePagePosition:(yposition?:number)=>Promise<void>;
notie:PageNotificationAdministrator;
accessToAPI:<T extends keyof APIFunctions_noChanging>(functionName: T, requiredObj: APIFunctions[T]["atServer"]) => Promise<APIFunctions[T]["atClient"]>
transition<T extends keyof PageStates>(nextState:T, requestObject:RequiredObjectType<PageStates[T]>):void
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/parts/NotificationList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { IView } from "../IView";
import { LanguageInApplication } from "../../../type/LanguageInApplication";
import { HTMLConverter } from "../../../utility/ViewUtility";
import marked from "marked";
import { formatDate } from "../../../utility/timeUtility";
import { formatDate } from "../../../utility/timeExpressionUtility";

export class NotificationList implements IView {
private container: Element;
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/parts/RecordCardView.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ScoreType } from "../../../type/list/IGameModeItem";
import { IRecordInShortResolved } from "../../../type/record/IRecord";
import { converseMiliSecondsIntoTime } from "../../../utility/timeUtility";
import { converseMiliSecondsIntoTime } from "../../../utility/timeExpressionUtility";
import { element, HTMLConverter, writeAbilityNameWithAttribute } from "../../../utility/ViewUtility";
import { IView } from "../IView";
import { TagsView } from "./TagsView";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IRecordResolved } from "../../../../type/record/IRecord";
import { converseMiliSecondsIntoTime, formatDate } from "../../../../utility/timeUtility";
import { converseMiliSecondsIntoTime, formatDate } from "../../../../utility/timeExpressionUtility";
import { HTMLConverter, writeAbilityNameWithAttribute } from "../../../../utility/ViewUtility";
import { IView } from "../../IView";
import { TagsView } from "../TagsView";
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/parts/RecordsGroupView.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { element, elementWithoutEscaping } from "../../../utility/ViewUtility";
import { convertNumberIntoDateString } from "../../../utility/timeUtility";
import { convertNumberIntoDateString } from "../../../utility/timeExpressionUtility";
import { IRecordGroupResolved } from "../../../type/record/IRecordGroupResolved";
import { IRecordInShortResolved } from "../../../type/record/IRecord";
import { createElementWithIdAndClass, findElementByClassNameWithErrorPossibility } from "../../utility/aboutElement";
Expand Down
63 changes: 42 additions & 21 deletions src/ts/client/view/parts/RuleIndexPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { choiceString } from "../../../utility/aboutLang";
import { elementWithoutEscaping } from "../../../utility/ViewUtility";
import { AppliedRuleClassResolved, RuleAttributeAndAppliedClassInfo } from "../../../type/api/gameRule/RuleAttributeAndAppliedClassInfo";
import { LanguageInApplication } from "../../../type/LanguageInApplication";
import { findElementByClassNameWithErrorPossibility } from "../../utility/aboutElement";
const contents={
ruleName:{
Japanese: "ルールの属性",
Expand All @@ -27,48 +28,68 @@ const contents={
Japanese: "全セグメント",
English: "All Segments"
},
ruleIndexClickable:{
Japanese: "下の目次をクリックすると、そのルールの詳細へ飛ぶことが出来ます。",
English: "If you click on the index below, you will jump to the detailed description of the rule."
},
specify_priority_in_ruleClasses:{
Japanese: "もっとも上にあるアイテムが基本的にルールとして優先されます。",
English: "If the scope of rule classes is duplicated and contradicts each other, the item at the top has priority."
}
}

type HandledType = {ruleInfo:RuleAttributeAndAppliedClassInfo, onClick:()=>void}
export class RuleIndexPart {
constructor(container: HTMLElement, { rules, language }: { rules: RuleAttributeAndAppliedClassInfo[]; language: LanguageInApplication; }) {
if (rules.length === 0) {
container.appendChild(elementWithoutEscaping`
private rules:HandledType[] = []
constructor(
private container: HTMLElement,
private language: LanguageInApplication
){
}
/**
* ルールの目次のアイテムを追加します
* これで追加し終えた後に、refrectViewメソッドを実行する必要があります。
*/
appendNewRule(ruleInfo:RuleAttributeAndAppliedClassInfo, onClick:()=>void){
this.rules.push({ruleInfo,onClick})
}
refrectView(){
if (this.rules.length === 0) {
this.container.appendChild(elementWithoutEscaping`
<div class="c-ruleIndex u-width90per">
<div class="__indexTitle">${choiceString(contents.indexTitleWithoutRules,language)}</div>
<div class="__indexTitle">${choiceString(contents.indexTitleWithoutRules,this.language)}</div>
<div>
`);
return
}
container.appendChild(elementWithoutEscaping`
<div class="c-ruleIndex u-width90per">
<div class="__indexTitle">${choiceString(contents.indexTitle,language).replace(/\$\{number\}/g,rules.length.toString())}</div>
<div class="__indexTitle u-bolderChara">${choiceString(contents.specify_priority_in_ruleClasses,language)}</div>
const ruleIndexSegment = this.container.appendChild(elementWithoutEscaping`
<div class="c-ruleIndex u-width90per u-clickable">
<div class="__indexTitle">${choiceString(contents.indexTitle,this.language).replace(/\$\{number\}/g,this.rules.length.toString())}</div>
<div class="__indexTitle">${choiceString(contents.ruleIndexClickable,this.language)}</div>
<div class="__indexTitle u-bolderChara">${choiceString(contents.specify_priority_in_ruleClasses,this.language)}</div>
<div class="__list">
<div class="__item --top u-smallerChara">
<p class=""><i class=""></i> ${choiceString(contents.ruleName,language)}</p> <p class="">${choiceString(contents.ruleClass,language)}</p>
<p class=""><i class=""></i> ${choiceString(contents.ruleName,this.language)}</p> <p class="">${choiceString(contents.ruleClass,this.language)}</p>
</div>
<hr noshade class="u-thin">
${rules.map((ruleObj) => this.generateRuleIndexHTML(ruleObj, language)).join("")}
</div>
<div>
`);
}
private generateRuleIndexHTML(ruleObj: RuleAttributeAndAppliedClassInfo, language: LanguageInApplication) {
return `<div class="__item">
<div><a class="u-bolderChara u-underline" href="#${ruleObj.rule.ruleName.replace(/\s/g,"_")}"><i class="${ruleObj.rule.iconCSS}"></i> ${ruleObj.rule.title}</a>
${(ruleObj.rule.note || 0) !== 0 ? ` <i class="u-redChara u-bolderChara">${choiceString(contents.annotated, language)}</i>` : ""}</div> <div class="__classItems">${this.generateClassDescriptionInRuleIndex(ruleObj.appliedClass, language)}</div>
</div>`;
const ruleIndexItemsSegment = findElementByClassNameWithErrorPossibility(ruleIndexSegment,"__list")
for (const {ruleInfo,onClick} of this.rules){
ruleIndexItemsSegment.appendChild(elementWithoutEscaping`
<div class="__item">
<div><i class="${ruleInfo.rule.iconCSS}"></i> ${ruleInfo.rule.title}
${(ruleInfo.rule.note || 0) !== 0 ? ` <i class="u-redChara u-bolderChara">${choiceString(contents.annotated, this.language)}</i>` : ""}</div> <div class="__classItems">${this.generateClassDescriptionInRuleIndex(ruleInfo.appliedClass, this.language)}</div>
</div>
`).addEventListener(`click`, onClick)
}
}
private generateClassDescriptionInRuleIndex(appliedClass: AppliedRuleClassResolved[], language: LanguageInApplication) {
return appliedClass.map(ruleClass => `
<div>
${this.generateCSSIcons(ruleClass)} [${ruleClass.scope || choiceString(contents.noScope,language)}]`
+ `${(ruleClass.note?.length || 0) !== 0 ? ` <i class="u-redChara u-bolderChara">${choiceString(contents.annotated, language)}</i>` : ""}
</div>`
<div>
${this.generateCSSIcons(ruleClass)} [${ruleClass.scope || choiceString(contents.noScope,language)}]`
+ `${(ruleClass.note?.length || 0) !== 0 ? ` <i class="u-redChara u-bolderChara">${choiceString(contents.annotated, language)}</i>` : ""}
</div>`
).join("");
}
private generateCSSIcons({ iconCSS }: { iconCSS: string[]; }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { appendElement, generateIcooonHTML } from "../../../../utility/aboutElem
import { TextInputCapsuled } from "../../TextInputCapsuled";
import { UListCupsuled } from "../../Input/UListCupsuled";
import { context_required, EditorPart } from "./EditorPart";
import { converseMiliSecondsIntoTime, convertTimeIntoNumber } from "../../../../../utility/timeUtility";
import { converseMiliSecondsIntoTime, convertTimeIntoNumber } from "../../../../../utility/timeExpressionUtility";
import { choiceString } from "../../../../../utility/aboutLang";

export class EditorRecordTimePart implements EditorPart<number> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { appendElement, generateIcooonHTML } from "../../../../utility/aboutElem
import { TextInputCapsuled } from "../../TextInputCapsuled";
import { UListCupsuled } from "../../Input/UListCupsuled";
import { context_required, EditorPart } from "./EditorPart";
import { convertScoreIntoNumber } from "../../../../../utility/timeUtility";
import { convertScoreIntoNumber } from "../../../../../utility/timeExpressionUtility";
import { choiceString } from "../../../../../utility/aboutLang";

export class EditorScorePart implements EditorPart<number> {
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/parts/gameModeCardsGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { elementWithoutEscaping } from "../../../utility/ViewUtility";
import { generateIcooonHTML, writeElement } from "../../utility/aboutElement";
import { IView } from "../IView";
import {IGameSystemInfoWithoutCollections} from "../../../type/list/IGameSystemInfo"
import {convertNumberIntoDateString}from "../../../utility/timeUtility"
import {convertNumberIntoDateString}from "../../../utility/timeExpressionUtility"
import { selectAppropriateDescription, choiceString } from "../../../utility/aboutLang"
import { IGameModeItemWithoutCollections } from "../../../type/list/IGameModeItem";
import { LanguageInApplication } from "../../../type/LanguageInApplication";
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/parts/gameSystemCardsGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { element, elementWithoutEscaping } from "../../../utility/ViewUtility";
import { generateIcooonHTML, writeElement } from "../../utility/aboutElement";
import { IView } from "../IView";
import {IGameSystemInfoWithoutCollections} from "../../../type/list/IGameSystemInfo"
import {convertNumberIntoDateString}from "../../../utility/timeUtility"
import {convertNumberIntoDateString}from "../../../utility/timeExpressionUtility"
import { selectAppropriateDescription, choiceString } from "../../../utility/aboutLang"
import { LanguageInApplication } from "../../../type/LanguageInApplication";
export class GameSystemCardGroup implements IView{
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/state/UserPageInWhole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { UserInformationBoard } from "../parts/UserInformationBoard";
import { IGameModeItemWithoutCollections } from "../../../type/list/IGameModeItem";
import { IGameSystemInfoWithoutCollections } from "../../../type/list/IGameSystemInfo";
import { choiceString, selectAppropriateDescription } from "../../../utility/aboutLang";
import { convertNumberIntoDateString } from "../../../utility/timeUtility";
import { convertNumberIntoDateString } from "../../../utility/timeExpressionUtility";
import { elementWithoutEscaping } from "../../../utility/ViewUtility";


Expand Down
10 changes: 7 additions & 3 deletions src/ts/client/view/state/gameModeRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,22 @@ export class S_GameModeRule extends PageStateBaseClass<{gameSystemID:string,game
if (this.requiredObj.gameSystemID === undefined) throw new Error("this.requiredObj.gameMode.rules === undefined")
const rules = (await this.app.accessToAPI("gameRule_get", {
gameSystemEnv:this.requiredObj,
language: this.app.state.language
language: this.app.state.language
})).result
if (rules === undefined) throw new Error("rules === undefined")
new RuleIndexPart(appendElement(this.articleDOM,"div","u-marginUpDown2em"),{rules,language:this.app.state.language})
const ruleIndexPart = new RuleIndexPart(appendElement(this.articleDOM,"div","u-marginUpDown2em"),this.app.state.language)

const ruleSegment = appendElement(this.articleDOM,"div","u-width90per")
for (const ruleObj of rules) {
const view = new GameModeRuleView(appendElement(ruleSegment,"div"),this.app.state.language)
const ruleDetailedSegment = appendElement(ruleSegment,"div")
const view = new GameModeRuleView(ruleDetailedSegment,this.app.state.language)
view.setHeader(ruleObj.rule)
view.setRule(ruleObj)
view.setNote(ruleObj.rule)
const destinationYPosition = ruleDetailedSegment.getBoundingClientRect().y + window.scrollY
ruleIndexPart.appendNewRule(ruleObj,() => this.app.scrollToThePagePosition(destinationYPosition))
}
ruleIndexPart.refrectView()
this.deleteLoadingSpinner()
}
private generateRuleIntroduction(){
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/state/gamemodeListOfPlayersPlayed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { IGameModeItemWithoutCollections } from "../../../type/list/IGameModeIte
import { IGameSystemInfoWithoutCollections } from "../../../type/list/IGameSystemInfo";
import { IRunner } from "../../../type/record/IRunner";
import { choiceString, selectAppropriateDescription } from "../../../utility/aboutLang";
import { convertNumberIntoDateString } from "../../../utility/timeUtility";
import { convertNumberIntoDateString } from "../../../utility/timeExpressionUtility";
import { elementWithoutEscaping } from "../../../utility/ViewUtility";
import { IAppUsedToReadAndChangePage } from "../../interface/AppInterfaces";
import { generateIcooonHTML, writeElement } from "../../utility/aboutElement";
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/state/mainMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { MultiLanguageString } from "../../../type/foundation/MultiLanguageStrin
import context from "./mainMenu.json"
import { NoticeView } from "../parts/notice";
import { choiceDescription } from "../../../utility/aboutLang";
import { formatDate } from "../../../utility/timeUtility";
import { formatDate } from "../../../utility/timeExpressionUtility";

export class S_MainMenu
extends PageStateBaseClass<null|{gameSystem:IGameSystemInfoWithoutCollections, gameMode:IGameModeItemWithoutCollections},IAppUsedToReadAndChangePage>{
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/state/modifyRecordForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export class S_ModifyRecordForm
}
private async sendInputInfo(gameSystemID:string,gameModeID:string,recordID:string,recordModified:ISentRecordOffer,reason:string){
try{
this.app.goToTop()
this.app.scrollToThePagePosition()
this.generateLoadingSpinner("cloud")

const language = this.app.state.language;
Expand Down
2 changes: 1 addition & 1 deletion src/ts/client/view/state/offerForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class S_OfferForm

private async decide(input:ISentRecordOffer){
try {
this.app.goToTop();
this.app.scrollToThePagePosition();
this.generateLoadingSpinner("cloud");
const detailRecord = (await this.app.accessToAPI("record_write",{
record:input,
Expand Down
3 changes: 3 additions & 0 deletions src/ts/utility/numericUtility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function fitInRange(min:number,x:number,max:number){
return Math.min(max,Math.max(min,x))
}
13 changes: 13 additions & 0 deletions src/ts/utility/timeAsyncUtility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* 指定したミリ秒後に解決するPromiseオブジェクトを渡します。
* @param miliSec 待つ時間
* @returns Promise<void>
* @example
* ```typescript
* // 30ミリ秒待機します。
* await miliseconds(30)
* ```
*/
export async function miliseconds(miliSec:number){
return new Promise<void>((resolve) => {window.setTimeout(() => resolve(), miliSec )})
}
File renamed without changes.

0 comments on commit 6a2012e

Please sign in to comment.