Merge branch 'main' into character-mods
This commit is contained in:
commit
7532455364
18 changed files with 349 additions and 158 deletions
|
|
@ -11,7 +11,7 @@ import JobSection from '~components/JobSection'
|
|||
import CharacterUnit from '~components/CharacterUnit'
|
||||
import CharacterConflictModal from '~components/CharacterConflictModal'
|
||||
|
||||
import type { JobSkillObject, SearchableObject } from '~types'
|
||||
import type { DetailsObject, JobSkillObject, SearchableObject } from '~types'
|
||||
|
||||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
|
|
@ -23,7 +23,7 @@ import './index.scss'
|
|||
interface Props {
|
||||
new: boolean
|
||||
characters?: GridCharacter[]
|
||||
createParty: () => Promise<AxiosResponse<any, any>>
|
||||
createParty: (details?: DetailsObject) => Promise<Party>
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
|
|
@ -95,13 +95,8 @@ const CharacterGrid = (props: Props) => {
|
|||
const character = object as Character
|
||||
|
||||
if (!party.id) {
|
||||
props.createParty().then((response) => {
|
||||
const party = response.data.party
|
||||
appState.party.id = party.id
|
||||
setSlug(party.shortcode)
|
||||
|
||||
if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`)
|
||||
saveCharacter(party.id, character, position)
|
||||
props.createParty().then((team) => {
|
||||
saveCharacter(team.id, character, position)
|
||||
.then((response) => storeGridCharacter(response.data))
|
||||
.catch((error) => console.error(error))
|
||||
})
|
||||
|
|
@ -184,19 +179,24 @@ const CharacterGrid = (props: Props) => {
|
|||
},
|
||||
}
|
||||
|
||||
if (party.id && appState.party.editable) {
|
||||
if (!party.id) {
|
||||
// If the party has no ID, create a new party
|
||||
await props.createParty()
|
||||
}
|
||||
|
||||
if (appState.party.id) {
|
||||
const response = await api.updateJob({
|
||||
partyId: party.id,
|
||||
partyId: appState.party.id,
|
||||
params: payload,
|
||||
})
|
||||
|
||||
const newParty = response.data
|
||||
const team = response.data
|
||||
|
||||
setJob(newParty.job)
|
||||
appState.party.job = newParty.job
|
||||
setJob(team.job)
|
||||
appState.party.job = team.job
|
||||
|
||||
setJobSkills(newParty.job_skills)
|
||||
appState.party.jobSkills = newParty.job_skills
|
||||
setJobSkills(team.job_skills)
|
||||
appState.party.jobSkills = team.job_skills
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const LabelledInput = React.forwardRef<HTMLInputElement, Props>(function Input(
|
|||
|
||||
// Classes
|
||||
const classes = classNames({ Input: true }, props.className)
|
||||
const { defaultValue, ...inputProps } = props
|
||||
const { defaultValue, visible, ...inputProps } = props
|
||||
|
||||
// Change value when prop updates
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import CharacterGrid from '~components/CharacterGrid'
|
|||
|
||||
import api from '~utils/api'
|
||||
import { appState, initialAppState } from '~utils/appState'
|
||||
import { GridType, TeamElement } from '~utils/enums'
|
||||
import { GridType } from '~utils/enums'
|
||||
import type { DetailsObject } from '~types'
|
||||
|
||||
import './index.scss'
|
||||
|
|
@ -40,63 +40,59 @@ const Party = (props: Props) => {
|
|||
}, [])
|
||||
|
||||
// Methods: Creating a new party
|
||||
async function createParty(extra: boolean = false) {
|
||||
return await api.endpoints.parties.create({
|
||||
party: {
|
||||
extra: extra,
|
||||
},
|
||||
})
|
||||
async function createParty(details?: DetailsObject) {
|
||||
let payload = {}
|
||||
if (details) payload = formatDetailsObject(details)
|
||||
|
||||
return await api.endpoints.parties
|
||||
.create(payload)
|
||||
.then((response) => storeParty(response.data.party))
|
||||
}
|
||||
|
||||
// Methods: Updating the party's details
|
||||
function checkboxChanged(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
appState.party.extra = event.target.checked
|
||||
async function updateDetails(details: DetailsObject) {
|
||||
if (!appState.party.id) return await createParty(details)
|
||||
else updateParty(details)
|
||||
}
|
||||
|
||||
if (party.id) {
|
||||
api.endpoints.parties.update(party.id, {
|
||||
party: { extra: event.target.checked },
|
||||
})
|
||||
function formatDetailsObject(details: DetailsObject) {
|
||||
const payload: { [key: string]: any } = {}
|
||||
|
||||
if (details.name) payload.name = details.name
|
||||
if (details.description) payload.description = details.description
|
||||
if (details.raid) payload.raid_id = details.raid.id
|
||||
if (details.chargeAttack) payload.charge_attack = details.chargeAttack
|
||||
if (details.fullAuto) payload.full_auto = details.fullAuto
|
||||
if (details.autoGuard) payload.auto_guard = details.autoGuard
|
||||
if (details.clearTime) payload.clear_time = details.clearTime
|
||||
if (details.buttonCount) payload.button_count = details.buttonCount
|
||||
if (details.chainCount) payload.chain_count = details.chainCount
|
||||
if (details.turnCount) payload.turn_count = details.turnCount
|
||||
if (details.extra) payload.extra = details.extra
|
||||
if (details.job) payload.job_id = details.job.id
|
||||
|
||||
if (Object.keys(payload).length > 1) return { party: payload }
|
||||
else return {}
|
||||
}
|
||||
|
||||
async function updateParty(details: DetailsObject) {
|
||||
const payload = formatDetailsObject(details)
|
||||
|
||||
if (appState.party.id) {
|
||||
return await api.endpoints.parties
|
||||
.update(appState.party.id, payload)
|
||||
.then((response) => storeParty(response.data.party))
|
||||
}
|
||||
}
|
||||
|
||||
function updateDetails(details: DetailsObject) {
|
||||
if (
|
||||
appState.party.name !== details.name ||
|
||||
appState.party.description !== details.description ||
|
||||
appState.party.raid?.id !== details.raid?.id
|
||||
) {
|
||||
if (appState.party.id)
|
||||
api.endpoints.parties
|
||||
.update(appState.party.id, {
|
||||
party: {
|
||||
name: details.name,
|
||||
description: details.description,
|
||||
raid_id: details.raid?.id,
|
||||
charge_attack: details.chargeAttack,
|
||||
full_auto: details.fullAuto,
|
||||
auto_guard: details.autoGuard,
|
||||
clear_time: details.clearTime,
|
||||
button_count: details.buttonCount,
|
||||
chain_count: details.chainCount,
|
||||
turn_count: details.turnCount,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
appState.party.name = details.name
|
||||
appState.party.description = details.description
|
||||
appState.party.raid = details.raid
|
||||
function checkboxChanged(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
appState.party.extra = event.target.checked
|
||||
|
||||
appState.party.chargeAttack = details.chargeAttack
|
||||
appState.party.fullAuto = details.fullAuto
|
||||
appState.party.autoGuard = details.autoGuard
|
||||
|
||||
appState.party.clearTime = details.clearTime
|
||||
appState.party.buttonCount = details.buttonCount
|
||||
appState.party.chainCount = details.chainCount
|
||||
appState.party.turnCount = details.turnCount
|
||||
|
||||
appState.party.updated_at = party.updated_at
|
||||
})
|
||||
// Only save if this is a saved party
|
||||
if (appState.party.id) {
|
||||
api.endpoints.parties.update(appState.party.id, {
|
||||
party: { extra: event.target.checked },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +122,7 @@ const Party = (props: Props) => {
|
|||
|
||||
// Methods: Storing party data
|
||||
const storeParty = function (team: Party) {
|
||||
// Store the important party and state-keeping values
|
||||
// Store the important party and state-keeping values in global state
|
||||
appState.party.name = team.name
|
||||
appState.party.description = team.description
|
||||
appState.party.raid = team.raid
|
||||
|
|
@ -147,6 +143,11 @@ const Party = (props: Props) => {
|
|||
storeCharacters(team.characters)
|
||||
storeWeapons(team.weapons)
|
||||
storeSummons(team.summons)
|
||||
|
||||
// Then, push the browser history to the new party's URL
|
||||
if (props.pushHistory) props.pushHistory(`/p/${team.shortcode}`)
|
||||
|
||||
return team
|
||||
}
|
||||
|
||||
const storeCharacters = (list: Array<GridCharacter>) => {
|
||||
|
|
|
|||
|
|
@ -252,11 +252,14 @@ const PartyDetails = (props: Props) => {
|
|||
}
|
||||
|
||||
function toggleDetails() {
|
||||
if (name !== party.name) {
|
||||
const resetName = party.name ? party.name : 'Untitled'
|
||||
setName(resetName)
|
||||
if (nameInput.current) nameInput.current.value = resetName
|
||||
}
|
||||
// Enabling this code will make live updates not work,
|
||||
// but I'm not sure why it's here, so we're not going to remove it.
|
||||
|
||||
// if (name !== party.name) {
|
||||
// const resetName = party.name ? party.name : ''
|
||||
// setName(resetName)
|
||||
// if (nameInput.current) nameInput.current.value = resetName
|
||||
// }
|
||||
setOpen(!open)
|
||||
}
|
||||
|
||||
|
|
@ -270,7 +273,6 @@ const PartyDetails = (props: Props) => {
|
|||
}
|
||||
|
||||
function updateDetails(event: React.MouseEvent) {
|
||||
const nameValue = nameInput.current?.value
|
||||
const descriptionValue = descriptionInput.current?.value
|
||||
const raid = raids.find((raid) => raid.slug === raidSlug)
|
||||
|
||||
|
|
@ -282,7 +284,7 @@ const PartyDetails = (props: Props) => {
|
|||
buttonCount: buttonCount,
|
||||
turnCount: turnCount,
|
||||
chainCount: chainCount,
|
||||
name: nameValue,
|
||||
name: name,
|
||||
description: descriptionValue,
|
||||
raid: raid,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,115 @@
|
|||
h3.priority {
|
||||
font-weight: $medium;
|
||||
font-size: $font-medium;
|
||||
margin-bottom: $unit;
|
||||
.Roadmap.Dialog {
|
||||
max-height: 60vh;
|
||||
overflow-y: scroll;
|
||||
|
||||
&.high {
|
||||
color: $red;
|
||||
.top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit;
|
||||
|
||||
h3.priority {
|
||||
font-weight: $medium;
|
||||
font-size: $font-large;
|
||||
|
||||
&.in_progress {
|
||||
color: $yellow;
|
||||
}
|
||||
|
||||
&.high {
|
||||
color: $red;
|
||||
}
|
||||
|
||||
&.mid {
|
||||
color: $orange-10;
|
||||
}
|
||||
|
||||
&.low {
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: $unit;
|
||||
}
|
||||
|
||||
.LinkItem {
|
||||
$diameter: $unit-6x;
|
||||
border: 1px solid var(--link-item-bg);
|
||||
border-radius: $card-corner;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--link-item-bg);
|
||||
|
||||
svg {
|
||||
fill: var(--link-item-image-color-hover);
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
padding: $unit-2x;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.Left {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: $unit-2x;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: var(--link-item-image-color);
|
||||
width: $diameter;
|
||||
height: auto;
|
||||
|
||||
&.ShareIcon {
|
||||
width: $unit-4x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: $bold;
|
||||
max-width: 70%;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.mid {
|
||||
color: $orange-10;
|
||||
.Separator {
|
||||
background: var(--separator-bg);
|
||||
border-radius: 2px;
|
||||
margin: $unit-3x 0;
|
||||
height: 2px;
|
||||
}
|
||||
p {
|
||||
color: var(--text-secondary);
|
||||
|
||||
font-size: $font-regular;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
&.low {
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
.notes {
|
||||
color: var(--text-primary);
|
||||
list-style-type: disc;
|
||||
|
||||
li {
|
||||
margin-bottom: $unit-half;
|
||||
.notes {
|
||||
color: var(--text-primary);
|
||||
list-style-type: none;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit;
|
||||
margin-bottom: $unit-2x;
|
||||
|
||||
h4 {
|
||||
font-size: $font-medium;
|
||||
font-weight: $bold;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: $font-regular;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@ import * as Dialog from '@radix-ui/react-dialog'
|
|||
|
||||
import CrossIcon from '~public/icons/Cross.svg'
|
||||
import ShareIcon from '~public/icons/Share.svg'
|
||||
import DiscordIcon from '~public/icons/discord.svg'
|
||||
import GithubIcon from '~public/icons/github.svg'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
const RoadmapModal = () => {
|
||||
const { t } = useTranslation('common')
|
||||
const { t } = useTranslation('roadmap')
|
||||
|
||||
return (
|
||||
<Dialog.Root>
|
||||
|
|
@ -22,13 +21,11 @@ const RoadmapModal = () => {
|
|||
</Dialog.Trigger>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Content
|
||||
className="Dialog"
|
||||
className="Roadmap Dialog"
|
||||
onOpenAutoFocus={(event) => event.preventDefault()}
|
||||
>
|
||||
<div className="DialogHeader">
|
||||
<Dialog.Title className="DialogTitle">
|
||||
{t('menu.roadmap')}
|
||||
</Dialog.Title>
|
||||
<Dialog.Title className="DialogTitle">{t('title')}</Dialog.Title>
|
||||
<Dialog.Close className="DialogClose" asChild>
|
||||
<span>
|
||||
<CrossIcon />
|
||||
|
|
@ -37,37 +34,52 @@ const RoadmapModal = () => {
|
|||
</div>
|
||||
|
||||
<section>
|
||||
<h3 className="priority high">High priority</h3>
|
||||
<div className="top">
|
||||
<h3 className="priority in_progress">{t('subtitle')}</h3>
|
||||
<p>{t('blurb')}</p>
|
||||
<p>{t('link.intro')}</p>
|
||||
<div className="LinkItem">
|
||||
<Link href="https://github.com/users/jedmund/projects/1/views/3">
|
||||
<a
|
||||
href="https://github.com/users/jedmund/projects/1/views/3"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<div className="Left">
|
||||
<GithubIcon />
|
||||
<h3>{t('link.title')}</h3>
|
||||
</div>
|
||||
<ShareIcon className="ShareIcon" />
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="Separator" />
|
||||
<ul className="notes">
|
||||
<li>URL state for team tabs</li>
|
||||
<li>
|
||||
More team details (Full Auto, Auto Guard, Clear Time) and
|
||||
filters
|
||||
<h4>{t('roadmap.item1.title')}</h4>
|
||||
<p>{t('roadmap.item1.description')}</p>
|
||||
</li>
|
||||
<li>
|
||||
Character mods - Rings, Earrings, Perpetuity Rings, Styles
|
||||
<h4>{t('roadmap.item2.title')}</h4>
|
||||
<p>{t('roadmap.item2.description')}</p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>{t('roadmap.item3.title')}</h4>
|
||||
<p>{t('roadmap.item3.description')}</p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>{t('roadmap.item4.title')}</h4>
|
||||
<p>{t('roadmap.item4.description')}</p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>{t('roadmap.item5.title')}</h4>
|
||||
<p>{t('roadmap.item5.description')}</p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>{t('roadmap.item6.title')}</h4>
|
||||
<p>{t('roadmap.item6.description')}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h3 className="priority mid">Medium priority</h3>
|
||||
<ul className="notes">
|
||||
<li>Dark mode improvements for logged out users</li>
|
||||
<li>Light Markdown in team details</li>
|
||||
<li>Transcendence Steps - Eternals and Bahamut</li>
|
||||
<li>Rearrange items in team</li>
|
||||
<li>Remove items from team</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h3 className="priority low">Low priority</h3>
|
||||
<ul className="notes">
|
||||
<li>Figure out DNS to simplify URLs to just granblue.team</li>
|
||||
<li>Unify About, Changelog, Roadmap</li>
|
||||
<li>Add R characters</li>
|
||||
<li>Add images for weird units like Aquors</li>
|
||||
<li>Character substitutions</li>
|
||||
<li>Deeper gbf.wiki integration</li>
|
||||
</ul>
|
||||
</section>
|
||||
</Dialog.Content>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import ExtraSummons from '~components/ExtraSummons'
|
|||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import { accountState } from '~utils/accountState'
|
||||
import type { SearchableObject } from '~types'
|
||||
import type { DetailsObject, SearchableObject } from '~types'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ import './index.scss'
|
|||
interface Props {
|
||||
new: boolean
|
||||
summons?: GridSummon[]
|
||||
createParty: () => Promise<AxiosResponse<any, any>>
|
||||
createParty: (details?: DetailsObject) => Promise<Party>
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
|
|
@ -86,14 +86,8 @@ const SummonGrid = (props: Props) => {
|
|||
const summon = object as Summon
|
||||
|
||||
if (!party.id) {
|
||||
props.createParty().then((response) => {
|
||||
const party = response.data.party
|
||||
appState.party.id = party.id
|
||||
setSlug(party.shortcode)
|
||||
|
||||
if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`)
|
||||
|
||||
saveSummon(party.id, summon, position).then((response) =>
|
||||
props.createParty().then((team) => {
|
||||
saveSummon(team.id, summon, position).then((response) =>
|
||||
storeGridSummon(response.data)
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import ExtraWeapons from '~components/ExtraWeapons'
|
|||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
|
||||
import type { SearchableObject } from '~types'
|
||||
import type { DetailsObject, SearchableObject } from '~types'
|
||||
|
||||
import './index.scss'
|
||||
import WeaponConflictModal from '~components/WeaponConflictModal'
|
||||
|
|
@ -24,7 +24,7 @@ import { accountState } from '~utils/accountState'
|
|||
interface Props {
|
||||
new: boolean
|
||||
weapons?: GridWeapon[]
|
||||
createParty: (extra: boolean) => Promise<AxiosResponse<any, any>>
|
||||
createParty: (details: DetailsObject) => Promise<Party>
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
|
|
@ -89,16 +89,11 @@ const WeaponGrid = (props: Props) => {
|
|||
if (position == 1) appState.party.element = weapon.element
|
||||
|
||||
if (!party.id) {
|
||||
props.createParty(party.extra).then((response) => {
|
||||
const party = response.data.party
|
||||
appState.party.id = party.id
|
||||
setSlug(party.shortcode)
|
||||
|
||||
if (props.pushHistory) props.pushHistory(`/p/${party.shortcode}`)
|
||||
|
||||
saveWeapon(party.id, weapon, position).then((response) =>
|
||||
const payload: DetailsObject = { extra: party.extra }
|
||||
props.createParty(payload).then((team) => {
|
||||
saveWeapon(team.id, weapon, position).then((response) => {
|
||||
storeGridWeapon(response.data.grid_weapon)
|
||||
)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
if (party.editable)
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
|||
meta: meta,
|
||||
raids: raids,
|
||||
sortedRaids: sortedRaids,
|
||||
...(await serverSideTranslations(locale, ['common'])),
|
||||
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
|
||||
// Will be passed to the page component as props
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
|||
raids: raids,
|
||||
sortedRaids: sortedRaids,
|
||||
weaponKeys: weaponKeys,
|
||||
...(await serverSideTranslations(locale, ['common'])),
|
||||
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
|
||||
// Will be passed to the page component as props
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,9 +190,9 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
|||
sortedRaids: sortedRaids,
|
||||
weaponKeys: weaponKeys,
|
||||
meta: {
|
||||
element: elementEmoji()
|
||||
element: elementEmoji(),
|
||||
},
|
||||
...(await serverSideTranslations(locale, ['common'])),
|
||||
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
|
||||
// Will be passed to the page component as props
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
|||
meta: meta,
|
||||
raids: raids,
|
||||
sortedRaids: sortedRaids,
|
||||
...(await serverSideTranslations(locale, ['common'])),
|
||||
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
|
||||
// Will be passed to the page component as props
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
|
|||
meta: meta,
|
||||
raids: raids,
|
||||
sortedRaids: sortedRaids,
|
||||
...(await serverSideTranslations(locale, ['common'])),
|
||||
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
|
||||
// Will be passed to the page component as props
|
||||
},
|
||||
}
|
||||
|
|
|
|||
44
public/locales/en/roadmap.json
Normal file
44
public/locales/en/roadmap.json
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"modals": {
|
||||
"roadmap": {
|
||||
"title": "Roadmap"
|
||||
}
|
||||
},
|
||||
"title": "Roadmap",
|
||||
"subtitle": "Next update",
|
||||
"blurb": "I'm aiming for this update to release between late-January and early-February. I'm losing a week to top 2k in Guild Wars and after that I'm back at my full-time job, so progress will be a bit slower.",
|
||||
"link": {
|
||||
"intro": "You can see the full roadmap on Github below:",
|
||||
"title": "granblue.team Roadmap"
|
||||
},
|
||||
"roadmap": {
|
||||
"item1": {
|
||||
"title": "Remix teams",
|
||||
"description": "See a team you want to riff off of? This update will let you remix other teams, which will add a copy to your account to make something new."
|
||||
},
|
||||
"item2": {
|
||||
"title": "Character mods",
|
||||
"description": "This update will allow you to add rings, earrings, perpetuity rings and awakenings to your characters."
|
||||
},
|
||||
"item3": {
|
||||
"title": "Remove from grid",
|
||||
"description": "This update will allow you to remove characters, summons, or weapons from your grid."
|
||||
},
|
||||
"item4": {
|
||||
"title": "Transcendence",
|
||||
"description": "This update will allow you to set which transcendence stage characters or summons in your team are at."
|
||||
},
|
||||
"item5": {
|
||||
"title": "URL state for team tabs",
|
||||
"description": "This update will allow you to append /characters, /weapons, /summons to link to individual tabs, and also /all to see everything at once."
|
||||
},
|
||||
"item6": {
|
||||
"title": "Add R characters",
|
||||
"description": "I will spend several hours manually inputting R characters, just for you."
|
||||
},
|
||||
"item7": {
|
||||
"title": "Private and unlisted teams",
|
||||
"description": "If you just want to save something for yourself, this update will let you change the visibility of teams so only you or people you share the link with can see them."
|
||||
}
|
||||
}
|
||||
}
|
||||
44
public/locales/ja/roadmap.json
Normal file
44
public/locales/ja/roadmap.json
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"modals": {
|
||||
"roadmap": {
|
||||
"title": "ロードマップ"
|
||||
}
|
||||
},
|
||||
"title": "ロードマップ",
|
||||
"subtitle": "次回更新予定",
|
||||
"blurb": "1月下旬〜2月上旬に更新する予定があります。火古戦場に2000位を狙っており、その後は仕事に戻るので開発はちょっとだけ遅くなります。",
|
||||
"link": {
|
||||
"intro": "全部のロードマップは以下のGithubリンクで:",
|
||||
"title": "granblue.teamのロードマップ"
|
||||
},
|
||||
"roadmap": {
|
||||
"item1": {
|
||||
"title": "編成をリミックス",
|
||||
"description": "面白い編成を見出したら、リミックス機能で自分のアカウントにコピーし、アイテムを変えて新らたな編成を作れる"
|
||||
},
|
||||
"item2": {
|
||||
"title": "キャラクター変更",
|
||||
"description": "指輪・御耳飾り・覚醒などキャラクターに付けるようになる"
|
||||
},
|
||||
"item3": {
|
||||
"title": "編成から外す",
|
||||
"description": "キャラクター・武器・召喚石などを編成から外すようになる"
|
||||
},
|
||||
"item4": {
|
||||
"title": "限界超越",
|
||||
"description": "編成にあるキャラクターや召喚石の限界超越のステージを記録するようになる"
|
||||
},
|
||||
"item5": {
|
||||
"title": "編成タブをURLで直接アクセス",
|
||||
"description": "編成URLに/characters・/weapons・/summonsを追加したら、そのタブを直接にアクセスできるようになり、/allを追加したら全てのタブを一気に見えるようになる。"
|
||||
},
|
||||
"item6": {
|
||||
"title": "Rキャラ追加",
|
||||
"description": "何時間もかかりますが追加します。"
|
||||
},
|
||||
"item7": {
|
||||
"title": "プライベートや未公開編成",
|
||||
"description": "自分や友達だけのために編成を作成したいなら、プライベートまたは未公開設定でできる。"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
--full-auto-text: #{$text--full--auto--light};
|
||||
|
||||
--separator-bg: #{$separator--bg--light};
|
||||
|
||||
// Light - Menus
|
||||
--dialog-bg: #{$dialog--bg--light};
|
||||
|
||||
|
|
@ -133,6 +135,8 @@
|
|||
|
||||
--full-auto-text: #{$text--full--auto--dark};
|
||||
|
||||
--separator-bg: #{$separator--bg--dark};
|
||||
|
||||
// Dark - Dialogs
|
||||
--dialog-bg: #{$dialog--bg--dark};
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ $orange-90: #ffebd9;
|
|||
// Colors -- Interface
|
||||
$blue: #275dc5;
|
||||
$red: #ff6161;
|
||||
$yellow: #c89d39;
|
||||
$error: #d13a3a;
|
||||
|
||||
// Colors -- Elements
|
||||
|
|
@ -130,6 +131,9 @@ $page--hover--dark: $grey-30;
|
|||
$page--element--bg--light: $grey-70;
|
||||
$page--element--bg--dark: $grey-40;
|
||||
|
||||
$separator--bg--light: $grey-90;
|
||||
$separator--bg--dark: $grey-15;
|
||||
|
||||
// Color Definitions: Dialog
|
||||
$dialog--bg--light: $grey-100;
|
||||
$dialog--bg--dark: $grey-25;
|
||||
|
|
@ -250,7 +254,7 @@ $text--primary--color--light: $grey-40;
|
|||
$text--primary--color--dark: $grey-90;
|
||||
|
||||
$text--secondary--color--light: $grey-60;
|
||||
$text--secondary--color--dark: $grey-60;
|
||||
$text--secondary--color--dark: $grey-70;
|
||||
|
||||
$text--tertiary--color--light: $grey-50;
|
||||
$text--tertiary--color--dark: $grey-50;
|
||||
|
|
|
|||
10
types/index.d.ts
vendored
10
types/index.d.ts
vendored
|
|
@ -22,16 +22,18 @@ export type PaginationObject = {
|
|||
|
||||
export type DetailsObject = {
|
||||
[key: string]: boolean | number | string | Raid | undefined
|
||||
fullAuto: boolean
|
||||
autoGuard: boolean
|
||||
chargeAttack: boolean
|
||||
clearTime: number
|
||||
fullAuto?: boolean
|
||||
autoGuard?: boolean
|
||||
chargeAttack?: boolean
|
||||
clearTime?: number
|
||||
buttonCount?: number
|
||||
turnCount?: number
|
||||
chainCount?: number
|
||||
name?: string
|
||||
description?: string
|
||||
raid?: Raid
|
||||
job?: Job
|
||||
extra?: boolean
|
||||
}
|
||||
|
||||
export type ExtendedMastery = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue