Merge pull request #217 from jedmund/updates-roadmap

Update static pages, small bugs, button revert
This commit is contained in:
Justin Edmund 2023-01-31 22:13:59 -08:00 committed by GitHub
commit 217c8a38a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 882 additions and 591 deletions

View file

@ -1,4 +1,85 @@
.About.PageContent {
$width: 520px;
padding-bottom: $unit-12x;
section {
display: flex;
flex-direction: column;
position: relative;
gap: $unit-2x;
z-index: 5;
.Hero {
position: absolute;
width: 40vw;
height: 80vh;
right: -18vw;
top: $unit-4x * -1;
z-index: 1;
background-image: linear-gradient(
90deg,
rgba(245, 245, 245, 1) 5%,
rgba(245, 245, 245, 0.2) 50%,
rgba(245, 245, 245, 0.2) 70%,
rgba(245, 245, 245, 1) 95%
),
linear-gradient(
rgba(245, 245, 245, 1) 5%,
rgba(245, 245, 245, 0.4) 40%,
rgba(245, 245, 245, 0.4) 78%,
rgba(245, 245, 245, 1) 95%
),
url('https://prd-game-a-granbluefantasy.akamaized.net/assets_en/img/sp/top/bg/bg_23.jpg');
@include breakpoint(tablet) {
right: -14vw;
width: 60vw;
}
@include breakpoint(phone) {
right: $unit-2x * -1;
width: 80vw;
&::before {
content: ' ';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
90deg,
rgba(245, 245, 245, 1) 0%,
rgba(245, 245, 245, 0) 50%,
rgba(245, 245, 245, 0) 70%,
rgba(245, 245, 245, 1) 95%
),
linear-gradient(
rgba(245, 245, 245, 1) 0%,
rgba(245, 245, 245, 0) 40%,
rgba(245, 245, 245, 0) 78%,
rgba(245, 245, 245, 1) 95%
);
z-index: 3;
}
}
}
p {
font-size: $font-medium;
max-width: $width;
line-height: 1.35;
z-index: 2;
}
h2 {
font-weight: $bold;
font-size: $font-medium;
margin: 0;
max-width: $width;
z-index: 2;
}
}
.Links {
display: grid;
gap: $unit;
@ -8,4 +89,8 @@
div.LinkItem {
margin-top: $unit-2x;
}
.LinkItem {
max-width: calc($width / 3 * 2);
}
}

View file

@ -2,7 +2,7 @@ import React from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
import { Trans, useTranslation } from 'next-i18next'
import ShareIcon from '~public/icons/Share.svg'
import DiscordIcon from '~public/icons/discord.svg'
@ -14,42 +14,35 @@ interface Props {}
const AboutPage: React.FC<Props> = (props: Props) => {
const { t: common } = useTranslation('common')
const { t: about } = useTranslation('about')
return (
<div className="About PageContent">
<h1>{common('about.segmented_control.about')}</h1>
<section>
<p>
Granblue.team is a tool to save and share team comps for{' '}
<a
href="https://game.granbluefantasy.jp"
target="_blank"
rel="noreferrer"
>
Granblue Fantasy
</a>
.
</p>
<p>
Start adding to a team and a URL will be created for you to share
wherever you like, no account needed.
</p>
<p>
However, if you do make an account, you can save any teams you find
for future reference and keep all of your teams together in one place.
</p>
<h2>
<Trans i18nKey="about:about.subtitle">
Granblue.team is a tool to save and share team compositions for{' '}
<a
href="https://game.granbluefantasy.jp"
target="_blank"
rel="noreferrer"
>
Granblue Fantasy
</a>
, a social RPG from Cygames.
</Trans>
</h2>
<p>{about('about.explanation.0')}</p>
<p>{about('about.explanation.1')}</p>
<div className="Hero" />
</section>
<section>
<h2>Feedback</h2>
<p>
This is an evolving project so feedback and suggestions are greatly
appreciated!
</p>
<p>
If you have a feature request, would like to report a bug, or are
enjoying the tool and want to say thanks, come hang out in Discord!
</p>
<div className="LinkItem">
<h2>{about('about.feedback.title')}</h2>
<p>{about('about.feedback.explanation')}</p>
<p>{about('about.feedback.solicit')}</p>
<div className="Discord LinkItem">
<Link href="https://discord.gg/qyZ5hGdPC8">
<a
href="https://discord.gg/qyZ5hGdPC8"
@ -67,66 +60,64 @@ const AboutPage: React.FC<Props> = (props: Props) => {
</section>
<section>
<h2>Credits</h2>
<h2>{about('about.credits.title')}</h2>
<p>
Granblue.team was built by{' '}
<a
href="https://twitter.com/jedmund"
target="_blank"
rel="noreferrer"
>
@jedmund
</a>{' '}
with a lot of help from{' '}
<a
href="https://twitter.com/lalalalinna"
target="_blank"
rel="noreferrer"
>
@lalalalinna
</a>{' '}
and{' '}
<a
href="https://twitter.com/tarngerine"
target="_blank"
rel="noreferrer"
>
@tarngerine
</a>
.
<Trans i18nKey="about:about.credits.maintainer">
Granblue.team was built and is maintained by{' '}
<a
href="https://twitter.com/jedmund"
target="_blank"
rel="noreferrer"
>
@jedmund
</a>
.
</Trans>
</p>
<p>
Many thanks also go to Disinfect, Slipper, Jif, Bless, 9highwind, and
everyone else in{' '}
<a
href="https://game.granbluefantasy.jp/#guild/detail/1190185"
target="_blank"
rel="noreferrer"
>
Fireplace
</a>{' '}
that helped with bug testing and feature requests. (P.S. We&apos;re
recruiting!) And yoey, but he won&apos;t join our crew.
<Trans i18nKey="about:about.credits.assistance">
Many thanks to{' '}
<a
href="https://twitter.com/lalalalinna"
target="_blank"
rel="noreferrer"
>
@lalalalinna
</a>{' '}
and{' '}
<a
href="https://twitter.com/tarngerine"
target="_blank"
rel="noreferrer"
>
@tarngerine
</a>
, who both provided a lot of help and advice as I was ramping up.
</Trans>
</p>
<p>
<Trans i18nKey="about:about.credits.support">
Many thanks also go to everyone in{' '}
<a
href="https://game.granbluefantasy.jp/#guild/detail/1190185"
target="_blank"
rel="noreferrer"
>
Fireplace
</a>{' '}
and the granblue-tools Discord for all of their help with with bug
testing, feature requests, and moral support. (P.S. We&apos;re
recruiting!)
</Trans>
</p>
</section>
<section>
<h2>Contributing</h2>
<p>
This app is open source and licensed under{' '}
<a
href="https://choosealicense.com/licenses/agpl-3.0/"
target="_blank"
rel="noreferrer"
>
GNU AGPLv3
</a>
. Plainly, that means you can download the source, modify it, and
redistribute it if you attribute this project, use the same license,
and keep it open source. You can contribute on Github.
</p>
<h2>{about('about.contributing.title')}</h2>
<p>{about('about.contributing.explanation')}</p>
<ul className="Links">
<li className="LinkItem">
<li className="Github LinkItem">
<Link href="https://github.com/jedmund/hensei-api">
<a
href="https://github.com/jedmund/hensei-api"
@ -141,7 +132,7 @@ const AboutPage: React.FC<Props> = (props: Props) => {
</a>
</Link>
</li>
<li className="LinkItem">
<li className="Github LinkItem">
<Link href="https://github.com/jedmund/hensei-web">
<a
href="https://github.com/jedmund/hensei-web"
@ -158,6 +149,27 @@ const AboutPage: React.FC<Props> = (props: Props) => {
</li>
</ul>
</section>
<section>
<h2>{about('about.license.title')}</h2>
<p>
<Trans i18nKey="about:about.license.license">
This app is licensed under{' '}
<a
href="https://choosealicense.com/licenses/agpl-3.0/"
target="_blank"
rel="noreferrer"
>
GNU AGPLv3
</a>
.
</Trans>
</p>
<p>{about('about.license.explanation')}</p>
</section>
<section>
<h2>{about('about.copyright.title')}</h2>
<p>{about('about.copyright.explanation')}</p>
</section>
</div>
)
}

View file

@ -9,6 +9,7 @@
font-weight: $normal;
gap: 6px;
transition: 0.18s opacity ease-in-out;
user-select: none;
&:hover,
&.Blended:hover,

View file

@ -1,7 +1,7 @@
.ChangelogUnit {
display: flex;
flex-direction: column;
gap: $unit-half;
gap: $unit;
img {
border-radius: $input-corner;
@ -12,5 +12,6 @@
font-size: $font-small;
font-weight: $medium;
text-align: center;
line-height: 1.4;
}
}

View file

@ -1,10 +1,11 @@
import React from 'react'
import { useRouter } from 'next/router'
import React, { useEffect, useState } from 'react'
import api from '~utils/api'
import './index.scss'
interface Props {
id: string
name: string
type: 'character' | 'summon' | 'weapon'
image?: '01' | '02' | '03' | '04'
}
@ -17,8 +18,52 @@ const defaultProps = {
image: '01',
}
const ChangelogUnit = ({ id, type, image, name }: Props) => {
function generateImageUrl() {
const ChangelogUnit = ({ id, type, image }: Props) => {
// Router
const router = useRouter()
const locale =
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
// State
const [item, setItem] = useState<Character | Weapon | Summon>()
// Hooks
useEffect(() => {
fetch()
}, [])
async function fetch() {
switch (type) {
case 'character':
const character = await fetchCharacter()
setItem(character.data)
break
case 'weapon':
const weapon = await fetchWeapon()
setItem(weapon.data)
break
case 'summon':
const summon = await fetchSummon()
setItem(summon.data)
break
}
}
async function fetchCharacter() {
return api.endpoints.characters.getOne({ id: id })
}
async function fetchWeapon() {
return api.endpoints.weapons.getOne({ id: id })
}
async function fetchSummon() {
return api.endpoints.summons.getOne({ id: id })
}
const imageUrl = () => {
let src = ''
switch (type) {
@ -37,9 +82,9 @@ const ChangelogUnit = ({ id, type, image, name }: Props) => {
}
return (
<div className="ChangelogUnit">
<img alt={name} src={generateImageUrl()} />
<h4>{name}</h4>
<div className="ChangelogUnit" key={id}>
<img alt={item ? item.name[locale] : ''} src={imageUrl()} />
<h4>{item ? item.name[locale] : ''}</h4>
</div>
)
}

View file

@ -1,6 +1,5 @@
import React, { useEffect, useState } from 'react'
import { subscribe, useSnapshot } from 'valtio'
import { subscribeKey } from 'valtio/utils'
import { deleteCookie } from 'cookies-next'
import { useRouter } from 'next/router'
import { Trans, useTranslation } from 'next-i18next'
@ -31,6 +30,7 @@ import ArrowIcon from '~public/icons/Arrow.svg'
import LinkIcon from '~public/icons/Link.svg'
import MenuIcon from '~public/icons/Menu.svg'
import RemixIcon from '~public/icons/Remix.svg'
import PlusIcon from '~public/icons/Add.svg'
import SaveIcon from '~public/icons/Save.svg'
import './index.scss'
@ -114,19 +114,9 @@ const Header = () => {
}
// Methods: Actions
function handleNewParty(event: React.MouseEvent, path: string) {
function handleNewTeam(event: React.MouseEvent) {
event.preventDefault()
// Clean state
const resetState = clonedeep(initialAppState)
Object.keys(resetState).forEach((key) => {
appState[key] = resetState[key]
})
// Push the root URL
router.push(path)
// Close right menu
newTeam()
closeRightMenu()
}
@ -165,6 +155,17 @@ const Header = () => {
return false
}
function newTeam() {
// Clean state
const resetState = clonedeep(initialAppState)
Object.keys(resetState).forEach((key) => {
appState[key] = resetState[key]
})
// Push the root URL
router.push('/new')
}
function remixTeam() {
setOriginalName(partySnapshot.name ? partySnapshot.name : t('no_title'))
@ -281,6 +282,20 @@ const Header = () => {
)
}
const newButton = () => {
return (
<Tooltip content={t('tooltips.new')}>
<Button
leftAccessoryIcon={<PlusIcon />}
className="New"
blended={true}
text={t('buttons.new')}
onClick={newTeam}
/>
</Tooltip>
)
}
const remixButton = () => {
return (
<Tooltip content={t('tooltips.remix')}>
@ -396,6 +411,7 @@ const Header = () => {
{router.route === '/p/[party]' && !appState.errorCode
? remixButton()
: ''}
{newButton()}
<DropdownMenu
open={rightMenuOpen}
onOpenChange={handleRightMenuOpenChange}
@ -483,13 +499,6 @@ const Header = () => {
<DropdownMenuLabel className="MenuLabel">
{account.user ? `@${account.user.username}` : t('no_user')}
</DropdownMenuLabel>
<DropdownMenuItem className="MenuItem">
<Link href="/new">
<a onClick={(e: React.MouseEvent) => handleNewParty(e, '/new')}>
{t('menu.new')}
</a>
</Link>
</DropdownMenuItem>
<DropdownMenuItem className="MenuItem">
<Link href={`/${account.user.username}` || ''} passHref>
<span>{t('menu.profile')}</span>
@ -513,16 +522,6 @@ const Header = () => {
} else {
items = (
<>
<DropdownMenuGroup className="MenuGroup">
<DropdownMenuItem className="MenuItem">
<Link href="/new">
<a onClick={(e: React.MouseEvent) => handleNewParty(e, '/new')}>
{t('menu.new')}
</a>
</Link>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup className="MenuGroup">
<DropdownMenuItem
className="MenuItem"

View file

@ -197,10 +197,14 @@ const JobSection = (props: Props) => {
/>
) : (
<div className="JobName">
<img
alt={party.job.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${party.job.granblue_id}.png`}
/>
{party.job ? (
<img
alt={party.job.name[locale]}
src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/job-icons/${party.job.granblue_id}.png`}
/>
) : (
''
)}
<h3>{party.job ? party.job.name[locale] : t('no_job')}</h3>
</div>
)}

View file

@ -199,6 +199,7 @@ const LoginModal = (props: Props) => {
email: '',
password: '',
})
setFormValid(false)
if (props.onOpenChange) props.onOpenChange(open)
}
@ -253,6 +254,7 @@ const LoginModal = (props: Props) => {
<div className="DialogFooter" ref={footerRef}>
<div className="Buttons Span">
<Button
contained={true}
disabled={!formValid}
text={t('modals.login.buttons.confirm')}
/>

View file

@ -1,4 +1,5 @@
.Roadmap.PageContent {
padding-bottom: $unit-12x;
h3.priority {
font-weight: $medium;
font-size: $font-large;
@ -29,10 +30,12 @@
p {
margin-bottom: $unit;
font-size: $font-medium;
}
.LinkItem {
$diameter: $unit-6x;
background: var(--dialog-bg);
border: 1px solid var(--link-item-bg);
border-radius: $card-corner;
@ -78,16 +81,12 @@
}
}
p {
color: var(--text-secondary);
font-size: $font-regular;
line-height: 1.3;
}
ul {
color: var(--text-primary);
list-style-type: none;
display: grid;
grid-template-columns: 1fr 1fr;
gap: $unit-3x;
li {
display: flex;

View file

@ -9,17 +9,18 @@ import GithubIcon from '~public/icons/github.svg'
import './index.scss'
interface Props {}
const ROADMAP_ITEMS = 6
const RoadmapPage: React.FC<Props> = (props: Props) => {
const RoadmapPage = () => {
const { t: common } = useTranslation('common')
const { t: roadmap } = useTranslation('roadmap')
const { t: about } = useTranslation('about')
return (
<div className="Roadmap PageContent">
<h1>{common('about.segmented_control.roadmap')}</h1>
<section className="notes">
<p>{roadmap('blurb')}</p>
<p>{roadmap('link.intro')}</p>
<p>{about('roadmap.blurb')}</p>
<p>{about('roadmap.link.intro')}</p>
<div className="LinkItem">
<Link href="https://github.com/users/jedmund/projects/1/views/3">
<a
@ -29,7 +30,7 @@ const RoadmapPage: React.FC<Props> = (props: Props) => {
>
<div className="Left">
<GithubIcon />
<h3>{roadmap('link.title')}</h3>
<h3>{about('roadmap.link.title')}</h3>
</div>
<ShareIcon className="ShareIcon" />
</a>
@ -38,32 +39,14 @@ const RoadmapPage: React.FC<Props> = (props: Props) => {
</section>
<section className="features">
<h3 className="priority in_progress">{roadmap('subtitle')}</h3>
<h3 className="priority in_progress">{about('roadmap.subtitle')}</h3>
<ul>
<li>
<h4>{roadmap('roadmap.item1.title')}</h4>
<p>{roadmap('roadmap.item1.description')}</p>
</li>
<li>
<h4>{roadmap('roadmap.item2.title')}</h4>
<p>{roadmap('roadmap.item2.description')}</p>
</li>
<li>
<h4>{roadmap('roadmap.item3.title')}</h4>
<p>{roadmap('roadmap.item3.description')}</p>
</li>
<li>
<h4>{roadmap('roadmap.item4.title')}</h4>
<p>{roadmap('roadmap.item4.description')}</p>
</li>
<li>
<h4>{roadmap('roadmap.item5.title')}</h4>
<p>{roadmap('roadmap.item5.description')}</p>
</li>
<li>
<h4>{roadmap('roadmap.item6.title')}</h4>
<p>{roadmap('roadmap.item6.description')}</p>
</li>
{[...Array(ROADMAP_ITEMS)].map((e, i) => (
<li key={`roadmap-${i}`}>
<h4>{about(`roadmap.items.${i}.title`)}</h4>
<p>{about(`roadmap.items.${i}.description`)}</p>
</li>
))}
</ul>
</section>
</div>

View file

@ -278,6 +278,7 @@ const SignupModal = (props: Props) => {
password: '',
passwordConfirmation: '',
})
setFormValid(false)
if (props.onOpenChange) props.onOpenChange(open)
}
@ -352,6 +353,7 @@ const SignupModal = (props: Props) => {
<div className="DialogFooter" ref={footerRef}>
<div className="Buttons Span">
<Button
contained={true}
disabled={!formValid}
text={t('modals.signup.buttons.confirm')}
/>

View file

@ -7,6 +7,7 @@
min-width: 3rem;
text-align: center;
padding: $unit ($unit * 1.5);
user-select: none;
&.ChargeAttack.On {
background: var(--charge-attack-bg);

View file

@ -1,6 +1,11 @@
.Tooltip {
transform-origin: var(--radix-tooltip-content-transform-origin);
animation: scaleIn $duration-zoom ease-out;
background: var(--dialog-bg);
border-radius: $card-corner;
border-radius: $input-corner;
color: var(--text-tertiary);
font-size: $font-tiny;
font-weight: $medium;
line-height: 1.3;
padding: $unit * 1.5;
z-index: 35;

View file

@ -1,41 +1,48 @@
.Updates.PageContent {
.version {
padding-bottom: $unit-12x;
.Version {
display: flex;
flex-direction: column;
gap: $unit-2x;
&.content {
.top h3 {
h3,
li,
p {
}
&.Content {
.Header h3 {
color: var(--accent-yellow);
}
.update {
display: flex;
flex-direction: column;
gap: $unit-2x;
}
.characters,
.weapons,
.summons {
.Contents {
display: grid;
grid-template-rows: 1fr auto;
gap: $unit;
& > h4 {
font-weight: $medium;
font-size: $font-regular;
}
}
.items {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr;
gap: $unit-4x;
.characters,
.weapons,
.summons {
display: grid;
grid-template-rows: auto 1fr;
gap: $unit;
& > h4 {
font-weight: $medium;
font-size: $font-regular;
}
.items {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: $unit-4x;
}
}
}
}
.top {
.Header {
align-items: baseline;
display: flex;
gap: $unit-half;
@ -54,32 +61,56 @@
}
}
.Notes {
display: grid;
grid-template-columns: repeat(3, minmax(200px, 1fr));
gap: $unit-2x;
.Contents {
display: flex;
flex-direction: column;
gap: $unit-4x;
li {
&.Bare {
display: flex;
flex-direction: column;
gap: $unit;
color: var(--text-primary);
list-style-type: disc;
list-style-position: inside;
gap: $unit-half;
h3 {
font-weight: $bold;
font-size: $font-regular;
}
img {
aspect-ratio: 4 / 3;
background: var(--dialog-bg);
border-radius: $input-corner;
display: block;
width: 100%;
}
p {
color: var(--text-primary);
li {
font-size: 14px;
}
}
section {
display: flex;
flex-direction: column;
gap: $unit-2x;
h2 {
margin: 0;
}
}
.Notes {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: $unit-2x;
li {
display: flex;
flex-direction: column;
gap: $unit;
h3 {
font-weight: $bold;
margin-top: $unit-half;
}
img {
aspect-ratio: 4 / 3;
background: var(--dialog-bg);
border-radius: $input-corner;
display: block;
width: 100%;
}
code {
background: var(--button-bg);
@ -91,29 +122,14 @@
}
}
}
}
.Bugs {
display: flex;
flex-direction: column;
list-style-type: disc;
list-style-position: inside;
gap: $unit;
li {
font-size: $font-regular;
.Bugs {
display: flex;
flex-direction: column;
list-style-type: disc;
gap: $unit-half;
padding-left: $unit-2x;
}
}
}
.notes {
color: var(--text-primary);
list-style-type: disc;
list-style-position: inside;
li {
margin-bottom: $unit-half;
font-size: $font-regular;
}
}
}

View file

@ -7,10 +7,30 @@ import ChangelogUnit from '~components/ChangelogUnit'
import './index.scss'
interface Props {}
const UpdatesPage: React.FC<Props> = (props: Props) => {
const UpdatesPage = () => {
const { t: common } = useTranslation('common')
const { t: updates } = useTranslation('updates')
const versionUpdates = {
'1.0.0': 5,
'1.0.1': 4,
'1.1.0': {
updates: 10,
bugs: 2,
images: [
'remix',
'unauth',
'transcendence',
'accessories',
'mastery',
'mechanics',
'rare',
'urls',
'nav',
'toasts',
],
},
}
function image(
alt: string,
@ -29,300 +49,167 @@ const UpdatesPage: React.FC<Props> = (props: Props) => {
return <img alt={alt} src={fallback} srcSet={sizes} />
}
return (
<div className="Updates PageContent">
<h1>{common('about.segmented_control.updates')}</h1>
<section className="version" data-version="1.1">
<div className="top">
<section className="Version" data-version="1.1">
<div className="Header">
<h3>1.1.0</h3>
<time>2023/02/06</time>
</div>
<section>
<h2>New features</h2>
<ul className="Notes">
<li>
{image(
'Remix parties',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'remix',
'jpg'
)}
<h3>Remix parties</h3>
<p>
See a team you want to try but don&apos;t have Yatima? Now you
can remix teams from other users to showcase substitutes, swap
for items you have, or just give it your own flavor.
</p>
</li>
<li>
{image(
'Transcendence',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'transcendence',
'jpg'
)}
<h3>Transcendence</h3>
<p>
Now you can set the transcendence stage for Eternals and select
summons (namely, Bahamut).
</p>
</li>
<li>
{image(
'Shields and Manatura',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'accessories',
'jpg'
)}
<h3>Shields and Manatura</h3>
<p>
When using Paladin or Manadiver, you can set their respective
Shield or Manatura from the button next to the main character.
</p>
</li>
<li>
{image(
'Character Mastery',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'mastery',
'jpg'
)}
<h3>Character Mastery</h3>
<p>
You can now add individual values for your character&apos;s
rings, earrings, and awakenings. Make sure to set your
Perpetuity Rings!
</p>
</li>
<li>
{image(
'Updated team mechanics',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'mechanics',
'jpg'
)}
<h3>Updated team mechanics</h3>
<p>Sorry, each party is only big enough for one Beelzebub.</p>
</li>
<li>
{image(
'R Characters',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'rare',
'jpg'
)}
<h3>R Characters</h3>
<p>
R Characters have been added to the database for your
memProving Grounds compositions.
</p>
</li>
<li>
{image(
'Unique URLs for team tabs',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'urls',
'jpg'
)}
<h3>Unique URLs for team tabs</h3>
<p>
You can now link to individual tabs directly. The site will do
it for you when you copy a URL, or you can append{' '}
<code>/characters</code>, <code>/weapons</code> or{' '}
<code>/summons</code> manually.
</p>
</li>
<li>
{image(
'Redesigned navigation',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'nav',
'jpg'
)}
<h3>Redesigned navigation</h3>
<p>
The top-navigation has been slightly redesigned. Click the party
name to copy its URL!
</p>
</li>
<li>
{image(
'Update toasts',
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
'toasts',
'jpg'
)}
<h3>Update toasts</h3>
<p>
The site will now show an update in the bottom-right corner when
new features or content is added.
</p>
</li>
</ul>
</section>
<section>
<h2>Bug fixes</h2>
<ul className="Bugs">
<li>
Fixed a bug that caused users to be logged out whenever they
restarted their browser
</li>
<li>Fixed a bug that caused Dark Opus weapons to disappear</li>
</ul>
</section>
<div className="Contents">
<section>
<h2>{updates('labels.features')}</h2>
<ul className="Notes">
{[...Array(versionUpdates['1.1.0'].updates)].map((e, i) => (
<li key={`1.1.0-update-${i}`}>
{image(
updates(`versions.1.1.0.features.${i}.title`),
`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/updates`,
versionUpdates['1.1.0'].images[i],
'jpg'
)}
<h3>{updates(`versions.1.1.0.features.${i}.title`)}</h3>
<p>{updates(`versions.1.1.0.features.${i}.blurb`)}</p>
</li>
))}
</ul>
</section>
<section>
<h2>Bug fixes</h2>
<ul className="Bugs">
{[...Array(versionUpdates['1.1.0'].bugs)].map((e, i) => (
<li key={`1.1.0-bugfix-${i}`}>
{updates(`versions.1.1.0.bugs.${i}`)}
</li>
))}
</ul>
</section>
</div>
</section>
<section className="content version" data-version="2022-12L">
<div className="top">
<h3>2023-01 Flash Gala</h3>
<section className="Content Version" data-version="2022-12L">
<div className="Header">
<h3>{`${updates('events.date', {
year: 2023,
month: 1,
})} ${updates('events.flash')}`}</h3>
<time>2023/01/19</time>
</div>
<div className="update">
<div className="Contents">
<section className="characters">
<h4>New characters</h4>
<h4>{updates('labels.characters')}</h4>
<div className="items">
<ChangelogUnit name="Amelia" id="3040444000" type="character" />
<ChangelogUnit
name="Halluel and Malluel (Grand)"
id="3040443000"
type="character"
/>
<ChangelogUnit id="3040444000" type="character" />
<ChangelogUnit id="3040443000" type="character" />
</div>
</section>
<section className="weapons">
<h4>New weapons</h4>
<h4>{updates('labels.weapons')}</h4>
<div className="items">
<ChangelogUnit
name="Shining Silver"
id="1040218300"
type="weapon"
/>
<ChangelogUnit
name="Eternal Signature"
id="1040116600"
type="weapon"
/>
<ChangelogUnit id="1040218300" type="weapon" />
<ChangelogUnit id="1040116600" type="weapon" />
</div>
</section>
</div>
</section>
<section className="content version" data-version="2023-01U">
<div className="top">
<h3>2023-01 Uncap</h3>
<section className="Content Version" data-version="2023-01U">
<div className="Header">
<h3>{`${updates('events.date', {
year: 2023,
month: 1,
})} ${updates('events.uncap')}`}</h3>
<time>2023/01/06</time>
</div>
<div className="update">
<div className="Contents">
<section className="characters">
<h4>Updated characters</h4>
<h4>{updates('labels.uncaps')}</h4>
<div className="items">
<ChangelogUnit
name="Shiva"
id="3040196000"
type="character"
image="03"
/>
<ChangelogUnit id="3040196000" type="character" image="03" />
</div>
</section>
</div>
</section>
<section className="version" data-version="1.0">
<div className="top">
<section className="Version" data-version="1.0">
<div className="Header">
<h3>1.0.1</h3>
<time>2023/01/08</time>
</div>
<ul className="notes">
<li>Extra party fields: Full Auto, Clear Time, and more</li>
<li>Support for Youtube short URLs</li>
<li>Responsive grids and lots of other mobile fixes</li>
<li>Many other bug fixes</li>
<ul className="Bare Contents">
{[...Array(versionUpdates['1.0.1'])].map((e, i) => (
<li key={`1.0.1-update-${i}`}>
{updates(`versions.1.0.1.features.${i}`)}
</li>
))}
</ul>
</section>
<section className="content version" data-version="2022-12L">
<div className="top">
<h3>2022-12 Legend Festival</h3>
<section className="Content Version" data-version="2022-12L">
<div className="Header">
<h3>{`${updates('events.date', { year: 2022, month: 12 })} ${updates(
'events.legfest'
)}`}</h3>
<time>2022/12/26</time>
</div>
<div className="update">
<div className="Contents">
<section className="characters">
<h4>New characters</h4>
<h4>{updates('labels.characters')}</h4>
<div className="items">
<ChangelogUnit
name="Michael (Grand)"
id="3040440000"
type="character"
/>
<ChangelogUnit name="Makura" id="3040441000" type="character" />
<ChangelogUnit
name="Ultimate Friday"
id="3040442000"
type="character"
/>
<ChangelogUnit id="3040440000" type="character" />
<ChangelogUnit id="3040441000" type="character" />
<ChangelogUnit id="3040442000" type="character" />
</div>
</section>
<section className="weapons">
<h4>New weapons</h4>
<h4>{updates('labels.weapons')}</h4>
<div className="items">
<ChangelogUnit
name="Crimson Scale"
id="1040315900"
type="weapon"
/>
<ChangelogUnit name="Leporidius" id="1040914500" type="weapon" />
<ChangelogUnit name="FRIED Spear" id="1040218200" type="weapon" />
<ChangelogUnit id="1040315900" type="weapon" />
<ChangelogUnit id="1040914500" type="weapon" />
<ChangelogUnit id="1040218200" type="weapon" />
</div>
</section>
<section className="summons">
<h4>New summons</h4>
<h4>{updates('labels.summons')}</h4>
<div className="items">
<ChangelogUnit name="Yatima" id="2040417000" type="summon" />
<ChangelogUnit id="2040417000" type="summon" />
</div>
</section>
</div>
</section>
<section className="content version" data-version="2022-12F2">
<div className="top">
<h3>2022-12 Flash Gala</h3>
<section className="Content Version" data-version="2022-12F2">
<div className="Header">
<h3>{`${updates('events.date', { year: 2022, month: 12 })} ${updates(
'events.flash'
)}`}</h3>
<time>2022/12/26</time>
</div>
<div className="update">
<div className="Contents">
<section className="characters">
<h4>New characters</h4>
<h4>{updates('labels.characters')}</h4>
<div className="items">
<ChangelogUnit
name="Charlotta (Grand)"
id="3040438000"
type="character"
/>
<ChangelogUnit name="Erin" id="3040439000" type="character" />
<ChangelogUnit id="3040438000" type="character" />
<ChangelogUnit id="3040439000" type="character" />
</div>
</section>
<section className="weapons">
<h4>New weapons</h4>
<h4>{updates('labels.weapons')}</h4>
<div className="items">
<ChangelogUnit
name="Claíomh Solais Díon"
id="1040024200"
type="weapon"
/>
<ChangelogUnit
name="Crystal Edge"
id="1040116500"
type="weapon"
/>
<ChangelogUnit id="1040024200" type="weapon" />
<ChangelogUnit id="1040116500" type="weapon" />
</div>
</section>
</div>
</section>
<section className="version" data-version="1.0">
<div className="top">
<section className="Version" data-version="1.0">
<div className="Header">
<h3>1.0.0</h3>
<time>2022/12/26</time>
</div>
<ul className="notes">
<li>First release!</li>
<li>You can embed Youtube videos now</li>
<li>Better clicking - right-click and open in a new tab</li>
<li>Manually set dark mode in Account Settings</li>
<li>Lots of bugs squashed</li>
<ul className="Bare Contents">
{[...Array(versionUpdates['1.0.0'])].map((e, i) => (
<li key={`1.0.0-update-${i}`}>
{updates(`versions.1.0.0.features.${i}`)}
</li>
))}
</ul>
</section>
</div>

View file

@ -384,7 +384,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
context: context,
version: version,
error: false,
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
} catch (error) {
@ -401,7 +401,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
code: response?.status,
text: response?.statusText,
},
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
}

View file

@ -165,7 +165,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
// Fetch and organize raids
return {
props: {
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common', 'about', 'updates'])),
// Will be passed to the page component as props
},
}

View file

@ -177,7 +177,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
context: context,
version: version,
error: false,
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
} catch (error) {
@ -194,7 +194,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
code: response?.status,
text: response?.statusText,
},
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
}

View file

@ -162,7 +162,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
context: context,
version: version,
error: false,
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
} catch (error) {
@ -180,7 +180,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
code: response?.status,
text: response?.statusText,
},
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
}

View file

@ -407,7 +407,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
context: context,
version: version,
error: false,
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
} catch (error) {
@ -424,7 +424,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
code: response?.status,
text: response?.statusText,
},
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
}

View file

@ -407,7 +407,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
context: context,
version: version,
error: false,
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
} catch (error) {
@ -424,7 +424,7 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex
code: response?.status,
text: response?.statusText,
},
...(await serverSideTranslations(locale, ['common', 'roadmap'])),
...(await serverSideTranslations(locale, ['common'])),
},
}
}

View file

@ -0,0 +1,80 @@
{
"modals": {
"roadmap": {
"title": "Roadmap"
}
},
"toasts": {
"title": "New update",
"description": {
"content": "New items have been added from the latest Granblue Fantasy update.",
"feature": "Now you can remix other people's teams, add Character rings and earrings, set Shields and Manatura on teams, and more!"
},
"button": "Learn more"
},
"about": {
"subtitle": "Granblue.team is a tool to save and share team compositions for <2>Granblue Fantasy</2>, a social RPG from Cygames.",
"explanation": [
"To get started, all you have to do is add an item to a team and a URL will be created for you to share wherever you like, no account needed.",
"If you do make an account, you can save any teams you find for future reference and keep all of your teams together in one place."
],
"feedback": {
"title": "Feedback",
"explanation": "If you have a feature request, would like to report a bug, or are enjoying the tool and want to say thanks, come hang out in Discord.",
"solicit": "Feedback and suggestions are greatly appreciated!"
},
"credits": {
"title": "Credits",
"maintainer": "Granblue.team was built and is maintained by <2>@jedmund</2>.",
"assistance": "Many thanks to <2>@lalalalinna</2> and <6>@tarngerine</6>, who both provided a lot of help and advice as I was ramping up.",
"support": "Many thanks also go to everyone in <2>Fireplace</2> and the granblue-tools Discord for all of their help with with bug testing, feature requests, and moral support. (P.S. We're recruiting!)"
},
"contributing": {
"title": "Contributing",
"explanation": "If you know how to program, this app is completely open-source. There's an abundance of features to build and bugs to fix, so help is always greatly appreciated!"
},
"license": {
"title": "License",
"license": "This app is licensed under <2>GNU AGPLv3</2>.",
"explanation": "Plainly, that means you can download the source, modify it, and redistribute it as long as you attribute this project, use the same license, and keep your derivative work open source as well."
},
"copyright": {
"title": "Copyright",
"explanation": "This app is a fan work. Granblue Fantasy and all characters, weapons, summons, items and artwork are wholly owned by Cygames, Inc."
}
},
"roadmap": {
"subtitle": "Next update",
"blurb": "The next major update is planned to come out in late-March to early-April, before the next Unite and Fight. I want to try to do some other things for a bit since I haven't been in a great place mentally, so development might be slower.",
"link": {
"intro": "You can see the full roadmap on Github below:",
"title": "granblue.team Roadmap"
},
"items": [
{
"title": "Account promotion",
"description": "Users that have created teams without an account will be able to create an account and retain access to all of their teams"
},
{
"title": "Better filters",
"description": "You'll be able to filter by team parameters like Full Auto or how many button clicks, and also filter out teams with no name, teams from anonymous users, and so on"
},
{
"title": "Private and Unlisted teams",
"description": "If you just want to make a team for your own memo or to share with your crew and no one else, this update is for you"
},
{
"title": "Mention items",
"description": "This update will allow you to mention individual items, like @Ixaba or @Charlotta (Grand), to give more context or suggest substitutions in your team descriptions."
},
{
"title": "Markdown in team descriptions",
"description": "If you're writing a lot of text in the description box, this update will give you tools to format it better"
},
{
"title": "Embed tweets in team descriptions",
"description": "Similar to embedding Youtube videos, this update will allow you to paste the link to a tweet and have it automatically embed in the description"
}
]
}
}

View file

@ -408,6 +408,7 @@
},
"tooltips": {
"copy_url": "Copy the URL to this team",
"new": "Create a new team",
"remix": "Make a copy of this team",
"save": "Save this team to your account",
"source": "Go to original team"

View file

@ -1,52 +0,0 @@
{
"modals": {
"roadmap": {
"title": "Roadmap"
}
},
"toasts": {
"title": "New update",
"description": {
"content": "New items have been added from the latest Granblue Fantasy update.",
"feature": "Now you can remix other people's teams, add Character rings and earrings, set Shields and Manatura on parties, and more!"
},
"button": "Learn more"
},
"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."
}
}
}

View file

@ -0,0 +1,82 @@
{
"labels": {
"characters": "New characters",
"weapons": "New weapons",
"summons": "New summons",
"uncaps": "New uncaps",
"features": "New features"
},
"events": {
"date": "{{month}}/{{year}}",
"legfest": "Legend Festival",
"flash": "Flash Gala",
"uncap": "Uncap"
},
"versions": {
"1.1.0": {
"features": [
{
"title": "Remix parties",
"blurb": "See a team you want to try but don't have Yatima? Now you can remix teams from other users to showcase substitutes, swap for items you have, or just give it your own flavor."
},
{
"title": "Accountless team editing",
"blurb": "Now you can edit parties you create later on, even if you don't make an account. You still won't have a profile, so make sure to bookmark them!"
},
{
"title": "Transcendence",
"blurb": "Now you can set the transcendence stage for Eternals and select summons (namely, Bahamut)."
},
{
"title": "Shields and Manatura",
"blurb": "When using Paladin or Manadiver, you can set their respective Shield or Manatura from the button next to the main character."
},
{
"title": "Character Mastery",
"blurb": "You can now add individual values for your character's rings, earrings, and awakenings. Make sure to set your Perpetuity Rings!"
},
{
"title": "Updated team mechanics",
"blurb": "Sorry, each party is only big enough for one Beelzebub."
},
{
"title": "R Characters",
"blurb": "R Characters have been added to the database for your mem—Proving Grounds compositions."
},
{
"title": "Unique URLs for team tabs",
"blurb": "You can now link to individual tabs directly. The site will do it for you when you copy a URL, or you can append /characters, /weapons or /summons manually."
},
{
"title": "Redesigned navigation",
"blurb": "The top-navigation has been slightly redesigned. Click the party name to copy its URL!"
},
{
"title": "Update toasts",
"blurb": "The site will now show an update in the bottom-right corner when new features or content is added."
}
],
"bugs": [
"Fixed a bug that caused users to be logged out whenever they restarted their browser",
"Fixed a bug that caused Dark Opus weapons to permanently disappear when adding them to a party that already had one"
]
},
"1.0.1": {
"features": [
"Extra party fields: Full Auto, Clear Time, and more",
"Support for Youtube short URLs",
"Responsive grids and lots of other mobile fixes",
"Many other bug fixes"
]
},
"1.0.0": {
"features": [
"First release!",
"You can embed Youtube videos now",
"Better click behavior: right-click to open in a new tab",
"Manually set dark mode in Account Settings",
"Lots of bugs squashed"
]
}
}
}

View file

@ -0,0 +1,80 @@
{
"modals": {
"roadmap": {
"title": "ロードマップ"
}
},
"toasts": {
"title": "新アプデ",
"description": {
"content": "グランブルーファンタジーの新アプデのコンテンツが追加しました。",
"feature": "編成をリミックスしたり、キャラの指輪や耳飾りを付けたり、盾やマナベリを装備したりことをできるようにしました。"
},
"button": "詳細をみる"
},
"about": {
"subtitle": "Granblue.teamは<2>グランブルーファンタジー</2>の編成を作成・保存・共有するサイトです。",
"explanation": [
"新しい編成にキャラクター・武器・召喚石を追加するだけで、好きな場所で共有できるURLが作成されます—アカウントなしで",
"しかしアカウントを作れば、見つけた編成を保存して今後の参考の参考にすることができますし、すべての編成を1つの場所にまとめておくことができます。"
],
"feedback": {
"title": "フィードバック",
"explanation": "もし、機能的な要望がある場合・バグを報告したい場合・あるいはこのサイトは役に立っているなら、Discordのサーバーに連絡ができます。",
"solicit": "ご意見、ご感想をお待ちしております。"
},
"credits": {
"title": "謝意",
"maintainer": "Granblue.teamの創造者・維持者は<2>@jedmund</2>.",
"assistance": "<2>@lalalalinna</2>さんと<6>@tarngerine</6>さんがプロジェクト開始の時にたくさん助かりました。",
"support": "<2>Fireplace</2>団アナザーver)とgranblue-toolsのDiscordの皆さんの協力も感謝しています。(募集中です!)"
},
"contributing": {
"title": "協力",
"explanation": "このサイトはオープンソースで協力したい方であったら、ご遠慮なくGitHubへ"
},
"license": {
"title": "ライセンス",
"license": "このサイトは<2>GNU AGPLv3</2>のライセンスで提供されています.",
"explanation": "派生のプロジェクトを作成したら、このプロジェクトをちゃんとリンクしてリンクし・派生のプロジェクトもオープンソースで同じライセンスで提供されたら、自由にソースコードをダウンロド・改変・再配布を許可されています。"
},
"copyright": {
"title": "著作権",
"explanation": "このサイトはファン制作です。グランブルーファンタジーおよびすべてのキャラクター・武器・召喚獣・アイテム・イラストなどは、株式会社Cygamesの完全所有物です。"
}
},
"roadmap": {
"subtitle": "次回更新予定",
"blurb": "次の古戦場の開場前3月下旬〜4月上旬に更新する予定があります。一生懸命頑張りましたのでちょっと休憩が取りたくて、マグナフェスもあるかもしれないので開発はゆっくりと進むと思います。",
"link": {
"intro": "全部のロードマップは以下のGithubリンクで:",
"title": "granblue.teamのロードマップ"
},
"items": [
{
"title": "アカウント昇進",
"description": "アカウントを登録せずに編成を作成した方が登場すると作った編成はアカウントに登録します。"
},
{
"title": "フィルター強化",
"description": "フルオート、押し数などでフィルターをできるようになり、無題無名の編成を見せないように設定できるようになる。"
},
{
"title": "プライベート、または非掲載編成",
"description": "自分だけのメモのために編成を作りたかったり、綺空団飲みとシェアした買ったりするならこの機能でできるようになる。"
},
{
"title": "様々なアイテムをメンション",
"description": "@イクサバ、@シャルロッテリミテッドverのようにメンションをすると、代理をおすすめしたり作戦について語ったりすることができるようになる。"
},
{
"title": "編成詳細にMarkdown入力",
"description": "詳細ボックスに作戦など多めのテキストを入力しようとすればMarkdownでより簡単にフォーマッティングできるようになる。"
},
{
"title": "詳細ボックスにツイート表示",
"description": "ツイートのURLを詳細ボックスに貼ると、ツイートは編成の下に表示するようになる。"
}
]
}
}

View file

@ -409,6 +409,7 @@
},
"tooltips": {
"copy_url": "この編成のURLをコピーする",
"new": "新しい編成を作成する",
"remix": "この編成の複製を作成する",
"save": "この編成をアカウントに保存する",
"source": "オリジナルの編成へ"

View file

@ -1,52 +0,0 @@
{
"modals": {
"roadmap": {
"title": "ロードマップ"
}
},
"toasts": {
"title": "新アプデ",
"description": {
"content": "グランブルーファンタジーの新アプデのコンテンツが追加しました。",
"feature": "編成をリミックスしたり、キャラの指輪や耳飾りを付けたり、盾やマナベリを装備したりことをできるようにしました。"
},
"button": "詳細をみる"
},
"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": "自分や友達だけのために編成を作成したいなら、プライベートまたは未公開設定でできる。"
}
}
}

View file

@ -0,0 +1,82 @@
{
"labels": {
"characters": "新キャラクター",
"weapons": "新武器",
"summons": "新召喚石",
"uncaps": "新上限解放",
"features": "新機能"
},
"events": {
"date": "{{year}}年{{month}}月",
"legfest": "レジェンドフェス",
"flash": "グランデフェス",
"uncap": "上限解放"
},
"versions": {
"1.1.0": {
"features": [
{
"title": "編成をリミックス",
"blurb": "見つけた編成をリミックスができるようになりました。編成をリミックスしたら、アイテムの代用を入れたり、自分の感想で作り直したりすることができます。"
},
{
"title": "アカウントなし編成改正",
"blurb": "登録しなくても作成した編成を後で改正することができるようになりました。プロフィールはまだないので是非URLをブックマークしてください"
},
{
"title": "限界超越",
"blurb": "十天衆、またはバハムートの限界超越レベルを入力することができるようになりました。"
},
{
"title": "盾やマナベリ装備可能",
"blurb": "ジョブはパラディンかマナダイバーの時、主人公の左にあるのボタンで盾やマナベリを装備できるようになりました。"
},
{
"title": "キャラのリミットボーナス",
"blurb": "キャラクターの指輪・耳飾り・覚醒のボーナスを設定できるようになりました。久遠の指輪も設定しましょう!"
},
{
"title": "編成ルール擁護",
"blurb": "編成のキャラクター・武器・召喚石の制限を実施されました。"
},
{
"title": "Rキャラ追加",
"blurb": "色々のコンテンツで使用しそうなのでRキャラが追加されました。"
},
{
"title": "編成タブごとのURL",
"blurb": "編成のタブに直接のリンクを作れるようになりました。URLをコピーする時にも直接のリンクになります。"
},
{
"title": "トップナビのリニューアル",
"blurb": "トップナビゲーションがちょっとリニューアルされました。編成名をクリックするとURLをコピーできます。"
},
{
"title": "アップデート告知",
"blurb": "サイトのアップデートの時に右下に告知が表示するようになりました。"
}
],
"bugs": [
"ブラウザを再起動するとログアウトしてしまう不具合を修正",
"終末武器をすでに装備している編成に追加すると、永久に消えてしまう不具合を修正"
]
},
"1.0.1": {
"features": [
"編成にフルオート、討伐時間などを入力できるようになりました",
"YouTubeの短いURLを入力できるようになりましたSupport for Youtube short URLs",
"モバイル向けのビジュアルバグを多め修正",
"その他のバグを多め修正"
]
},
"1.0.0": {
"features": [
"初アップデート!",
"YouTubeの動画を埋め込めるようになりました",
"右クリックで新しいタブでいろいろのリンクを開けるようになりました",
"アカウント設定でダークモードが設定するようになりました",
"その他のバグを多め修正"
]
}
}
}

View file

@ -138,33 +138,56 @@ select {
margin-bottom: $unit * 3;
}
p {
color: var(--text-secondary);
font-size: $font-regular;
p,
li {
color: var(--text-primary);
font-size: 14px;
line-height: 1.3;
margin-bottom: $unit;
&:last-of-type {
margin-bottom: 0;
}
}
.LinkItem {
$diameter: $unit-6x;
align-items: center;
background: var(--dialog-bg);
border: 1px solid var(--link-item-bg);
border-radius: $card-corner;
display: flex;
min-height: 82px;
transition: background $duration-zoom ease-in,
transform $duration-zoom ease-in;
&:hover {
background-color: var(--link-item-bg);
background: var(--link-item-bg);
color: var(--text-primary);
svg {
fill: var(--link-item-image-color-hover);
.ShareIcon {
fill: var(--text-primary);
transform: translate($unit-half, calc(($unit * -1) / 2));
}
}
&.Github {
.Left svg {
background: white;
border-radius: calc($diameter / 2);
}
&:hover {
.Left svg {
fill: #6e5494;
}
}
}
&.Discord:hover .Left svg {
fill: #5865f2;
}
a {
display: flex;
justify-content: space-between;
padding: $unit-2x;
width: 100%;
&:hover {
text-decoration: none;
@ -187,6 +210,7 @@ select {
fill: var(--link-item-image-color);
width: $diameter;
height: auto;
transition: fill $duration-zoom ease-in;
&.ShareIcon {
width: $unit-4x;

View file

@ -168,6 +168,9 @@ class Api {
const api: Api = new Api({ url: process.env.NEXT_PUBLIC_SIERO_API_URL || 'https://localhost:3000/api/v1'})
api.createEntity({ name: 'users' })
api.createEntity({ name: 'parties' })
api.createEntity({ name: 'characters' })
api.createEntity({ name: 'weapons' })
api.createEntity({ name: 'summons' })
api.createEntity({ name: 'grid_characters' })
api.createEntity({ name: 'grid_weapons' })
api.createEntity({ name: 'grid_summons' })