Merge branch 'staging' of github.com:jedmund/hensei-web into staging
This commit is contained in:
commit
9de87abd1e
26 changed files with 384 additions and 369 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -58,6 +58,7 @@ public/images/mastery*
|
|||
public/images/updates*
|
||||
public/images/guidebooks*
|
||||
public/images/raids*
|
||||
public/images/gacha*
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
|
|
|||
|
|
@ -47,32 +47,32 @@
|
|||
|
||||
&.fire {
|
||||
background: var(--fire-bg);
|
||||
color: var(--fire-text);
|
||||
color: var(--fire-hover-text);
|
||||
}
|
||||
|
||||
&.water {
|
||||
background: var(--water-bg);
|
||||
color: var(--water-text);
|
||||
color: var(--water-hover-text);
|
||||
}
|
||||
|
||||
&.earth {
|
||||
background: var(--earth-bg);
|
||||
color: var(--earth-text);
|
||||
color: var(--earth-hover-text);
|
||||
}
|
||||
|
||||
&.wind {
|
||||
background: var(--wind-bg);
|
||||
color: var(--wind-text);
|
||||
color: var(--wind-hover-text);
|
||||
}
|
||||
|
||||
&.dark {
|
||||
background: var(--dark-bg);
|
||||
color: var(--dark-text);
|
||||
color: var(--dark-hover-text);
|
||||
}
|
||||
|
||||
&.light {
|
||||
background: var(--light-bg);
|
||||
color: var(--light-text);
|
||||
color: var(--light-hover-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,23 @@
|
|||
}
|
||||
}
|
||||
|
||||
.Filter.Button {
|
||||
justify-content: center;
|
||||
|
||||
.Text {
|
||||
display: none;
|
||||
width: auto;
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@include breakpoint(phone) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.UserInfo {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -181,6 +181,7 @@ const FilterBar = (props: Props) => {
|
|||
className={filterButtonClasses}
|
||||
blended={true}
|
||||
leftAccessoryIcon={<FilterIcon />}
|
||||
text={t('filters.name')}
|
||||
onClick={() => setFilterModalOpen(true)}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import classNames from 'classnames'
|
|||
import clonedeep from 'lodash.clonedeep'
|
||||
import Link from 'next/link'
|
||||
|
||||
import api from '~utils/api'
|
||||
import { accountState, initialAccountState } from '~utils/accountState'
|
||||
import { appState, initialAppState } from '~utils/appState'
|
||||
import { getLocalId } from '~utils/localId'
|
||||
|
|
@ -32,11 +31,8 @@ import Tooltip from '~components/common/Tooltip'
|
|||
import * as Switch from '@radix-ui/react-switch'
|
||||
|
||||
import ChevronIcon from '~public/icons/Chevron.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'
|
||||
|
||||
|
|
@ -51,7 +47,6 @@ const Header = () => {
|
|||
const localeData = retrieveLocaleCookies()
|
||||
|
||||
// State management
|
||||
const [copyToastOpen, setCopyToastOpen] = useState(false)
|
||||
const [remixToastOpen, setRemixToastOpen] = useState(false)
|
||||
const [loginModalOpen, setLoginModalOpen] = useState(false)
|
||||
const [signupModalOpen, setSignupModalOpen] = useState(false)
|
||||
|
|
@ -64,7 +59,6 @@ const Header = () => {
|
|||
const [originalName, setOriginalName] = useState('')
|
||||
|
||||
// Snapshots
|
||||
const { account } = useSnapshot(accountState)
|
||||
const { party: partySnapshot } = useSnapshot(appState)
|
||||
|
||||
// Subscribe to app state to listen for party name and
|
||||
|
|
@ -108,15 +102,6 @@ const Header = () => {
|
|||
setRightMenuOpen(false)
|
||||
}
|
||||
|
||||
// Methods: Event handlers (Copy toast)
|
||||
function handleCopyToastOpenChanged(open: boolean) {
|
||||
setCopyToastOpen(open)
|
||||
}
|
||||
|
||||
function handleCopyToastCloseClicked() {
|
||||
setCopyToastOpen(false)
|
||||
}
|
||||
|
||||
// Methods: Event handlers (Remix toasts)
|
||||
function handleRemixToastOpenChanged(open: boolean) {
|
||||
setRemixToastOpen(open)
|
||||
|
|
@ -142,23 +127,6 @@ const Header = () => {
|
|||
router.push(router.asPath, undefined, { locale: language })
|
||||
}
|
||||
|
||||
function copyToClipboard() {
|
||||
const path = router.asPath.split('/')[1]
|
||||
|
||||
if (path === 'p') {
|
||||
const el = document.createElement('input')
|
||||
el.value = window.location.href
|
||||
el.id = 'url-input'
|
||||
document.body.appendChild(el)
|
||||
|
||||
el.select()
|
||||
document.execCommand('copy')
|
||||
el.remove()
|
||||
|
||||
setCopyToastOpen(true)
|
||||
}
|
||||
}
|
||||
|
||||
function logout() {
|
||||
// Close menu
|
||||
closeRightMenu()
|
||||
|
|
@ -188,84 +156,6 @@ const Header = () => {
|
|||
router.push('/new')
|
||||
}
|
||||
|
||||
function remixTeam() {
|
||||
setOriginalName(partySnapshot.name ? partySnapshot.name : t('no_title'))
|
||||
|
||||
if (partySnapshot.shortcode) {
|
||||
const body = getLocalId()
|
||||
api
|
||||
.remix({ shortcode: partySnapshot.shortcode, body: body })
|
||||
.then((response) => {
|
||||
const remix = response.data.party
|
||||
|
||||
// Store the edit key in local storage
|
||||
if (remix.edit_key) {
|
||||
storeEditKey(remix.id, remix.edit_key)
|
||||
setEditKey(remix.id, remix.user)
|
||||
}
|
||||
|
||||
router.push(`/p/${remix.shortcode}`)
|
||||
setRemixToastOpen(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFavorite() {
|
||||
if (partySnapshot.favorited) unsaveFavorite()
|
||||
else saveFavorite()
|
||||
}
|
||||
|
||||
function saveFavorite() {
|
||||
if (partySnapshot.id)
|
||||
api.saveTeam({ id: partySnapshot.id }).then((response) => {
|
||||
if (response.status == 201) appState.party.favorited = true
|
||||
})
|
||||
else console.error('Failed to save team: No party ID')
|
||||
}
|
||||
|
||||
function unsaveFavorite() {
|
||||
if (partySnapshot.id)
|
||||
api.unsaveTeam({ id: partySnapshot.id }).then((response) => {
|
||||
if (response.status == 200) appState.party.favorited = false
|
||||
})
|
||||
else console.error('Failed to unsave team: No party ID')
|
||||
}
|
||||
|
||||
// Rendering: Elements
|
||||
const pageTitle = () => {
|
||||
let title = ''
|
||||
let hasAccessory = false
|
||||
|
||||
const path = router.asPath.split('/')[1]
|
||||
if (path === 'p') {
|
||||
hasAccessory = true
|
||||
if (appState.party && appState.party.name) {
|
||||
title = appState.party.name
|
||||
} else {
|
||||
title = t('no_title')
|
||||
}
|
||||
} else {
|
||||
title = ''
|
||||
}
|
||||
|
||||
return title !== '' ? (
|
||||
<Tooltip content={t('tooltips.copy_url')}>
|
||||
<Button
|
||||
blended={true}
|
||||
rightAccessoryIcon={
|
||||
path === 'p' && hasAccessory ? (
|
||||
<LinkIcon className="stroke" />
|
||||
) : undefined
|
||||
}
|
||||
text={title}
|
||||
onClick={copyToClipboard}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : (
|
||||
''
|
||||
)
|
||||
}
|
||||
|
||||
const profileImage = () => {
|
||||
let image
|
||||
|
||||
|
|
@ -310,21 +200,6 @@ const Header = () => {
|
|||
)
|
||||
}
|
||||
|
||||
// Rendering: Toasts
|
||||
const urlCopyToast = () => {
|
||||
return (
|
||||
<Toast
|
||||
altText={t('toasts.copied')}
|
||||
open={copyToastOpen}
|
||||
duration={2400}
|
||||
type="foreground"
|
||||
content={t('toasts.copied')}
|
||||
onOpenChange={handleCopyToastOpenChanged}
|
||||
onCloseClick={handleCopyToastCloseClicked}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const remixToast = () => {
|
||||
return (
|
||||
<Toast
|
||||
|
|
@ -394,7 +269,6 @@ const Header = () => {
|
|||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
{!appState.errorCode ? pageTitle() : ''}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -564,8 +438,6 @@ const Header = () => {
|
|||
<nav id="Header">
|
||||
{left()}
|
||||
{right()}
|
||||
{urlCopyToast()}
|
||||
{remixToast()}
|
||||
{settingsModal()}
|
||||
{loginModal()}
|
||||
{signupModal()}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,14 @@
|
|||
max-width: 30vw;
|
||||
padding: $unit * 4;
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
max-width: inherit;
|
||||
max-width: 60vw;
|
||||
}
|
||||
|
||||
@include breakpoint(phone) {
|
||||
max-width: inherit;
|
||||
width: 60vw;
|
||||
width: 70vw;
|
||||
}
|
||||
|
||||
.description {
|
||||
|
|
@ -41,5 +46,15 @@
|
|||
display: flex;
|
||||
align-self: flex-end;
|
||||
gap: $unit;
|
||||
|
||||
@include breakpoint(phone) {
|
||||
flex-direction: column-reverse;
|
||||
align-self: center;
|
||||
width: 100%;
|
||||
|
||||
.Button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
.Joined .Input::placeholder {
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
|
@ -56,6 +56,7 @@ const CharLimitedFieldset: ForwardRefRenderFunction<HTMLInputElement, Props> = (
|
|||
<div className={classNames({ Joined: true }, props.className)}>
|
||||
<input
|
||||
{...props}
|
||||
data-1p-ignore
|
||||
autoComplete="off"
|
||||
className="Input"
|
||||
type={props.type}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,6 @@
|
|||
|
||||
.Input::placeholder {
|
||||
/* Chrome, Firefox, Opera, Safari 10.1+ */
|
||||
color: var(--text-secondary) !important;
|
||||
color: var(--text-secondary);
|
||||
opacity: 1; /* Firefox */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
padding: $unit;
|
||||
transform-origin: var(--radix-popover-content-transform-origin);
|
||||
width: var(--radix-popover-trigger-width);
|
||||
min-width: 440px;
|
||||
z-index: 5;
|
||||
|
||||
@include breakpoint(phone) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
color: var(--full-auto-text);
|
||||
}
|
||||
|
||||
&.AutoGuard.On {
|
||||
&.AutoGuard.On,
|
||||
&.AutoSummon.On {
|
||||
background: var(--auto-guard-bg);
|
||||
color: var(--auto-guard-text);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const RemixTeamAlert = ({
|
|||
<Trans i18nKey="modals.remix_team.description.viewer">
|
||||
Remixing a team makes a copy of it in your account so you can make
|
||||
your own changes.\n\nWould you like to remix{' '}
|
||||
<strong>{{ name: 'HEY' }}</strong>?
|
||||
<strong>{{ name: name }}</strong>?
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import {
|
||||
|
|
@ -22,6 +23,8 @@ import TableField from '~components/common/TableField'
|
|||
import type { DetailsObject } from 'types'
|
||||
import type { DialogProps } from '@radix-ui/react-dialog'
|
||||
|
||||
import { appState } from '~utils/appState'
|
||||
|
||||
import CheckIcon from '~public/icons/Check.svg'
|
||||
import CrossIcon from '~public/icons/Cross.svg'
|
||||
import './index.scss'
|
||||
|
|
@ -31,14 +34,16 @@ interface Props extends DialogProps {
|
|||
updateCallback: (details: DetailsObject) => void
|
||||
}
|
||||
|
||||
const EditPartyModal = ({ party, updateCallback, ...props }: Props) => {
|
||||
const EditPartyModal = ({ updateCallback, ...props }: Props) => {
|
||||
// Set up router
|
||||
const router = useRouter()
|
||||
const locale = router.locale
|
||||
|
||||
// Set up translation
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
// Set up reactive state
|
||||
const { party } = useSnapshot(appState)
|
||||
|
||||
// Refs
|
||||
const headerRef = React.createRef<HTMLDivElement>()
|
||||
const footerRef = React.createRef<HTMLDivElement>()
|
||||
|
|
@ -54,6 +59,7 @@ const EditPartyModal = ({ party, updateCallback, ...props }: Props) => {
|
|||
|
||||
// States: Data
|
||||
const [name, setName] = useState('')
|
||||
const [description, setDescription] = useState('')
|
||||
const [raid, setRaid] = useState<Raid>()
|
||||
const [extra, setExtra] = useState(false)
|
||||
const [chargeAttack, setChargeAttack] = useState(true)
|
||||
|
|
@ -68,24 +74,15 @@ const EditPartyModal = ({ party, updateCallback, ...props }: Props) => {
|
|||
|
||||
// Hooks
|
||||
useEffect(() => {
|
||||
if (!party) return
|
||||
|
||||
setName(party.name)
|
||||
setRaid(party.raid)
|
||||
setAutoGuard(party.auto_guard)
|
||||
setAutoSummon(party.auto_summon)
|
||||
setFullAuto(party.full_auto)
|
||||
setChargeAttack(party.charge_attack)
|
||||
setClearTime(party.clear_time)
|
||||
if (party.turn_count) setTurnCount(party.turn_count)
|
||||
if (party.button_count) setButtonCount(party.button_count)
|
||||
if (party.chain_count) setChainCount(party.chain_count)
|
||||
persistFromState()
|
||||
}, [party])
|
||||
|
||||
// Methods: Event handlers (Dialog)
|
||||
function openChange() {
|
||||
if (open) {
|
||||
setOpen(false)
|
||||
setCurrentSegment(0)
|
||||
persistFromState()
|
||||
if (props.onOpenChange) props.onOpenChange(false)
|
||||
} else {
|
||||
setOpen(true)
|
||||
|
|
@ -176,6 +173,21 @@ const EditPartyModal = ({ party, updateCallback, ...props }: Props) => {
|
|||
}
|
||||
|
||||
// Methods: Data methods
|
||||
function persistFromState() {
|
||||
if (!party) return
|
||||
setName(party.name ? party.name : '')
|
||||
setDescription(party.description ? party.description : '')
|
||||
setRaid(party.raid)
|
||||
setAutoGuard(party.autoGuard)
|
||||
setAutoSummon(party.autoSummon)
|
||||
setFullAuto(party.fullAuto)
|
||||
setChargeAttack(party.chargeAttack)
|
||||
setClearTime(party.clearTime)
|
||||
if (party.turnCount) setTurnCount(party.turnCount)
|
||||
if (party.buttonCount) setButtonCount(party.buttonCount)
|
||||
if (party.chainCount) setChainCount(party.chainCount)
|
||||
}
|
||||
|
||||
function updateDetails(event: React.MouseEvent) {
|
||||
const descriptionValue = descriptionInput.current?.value
|
||||
const details: DetailsObject = {
|
||||
|
|
@ -272,9 +284,8 @@ const EditPartyModal = ({ party, updateCallback, ...props }: Props) => {
|
|||
}
|
||||
onChange={handleTextAreaChanged}
|
||||
ref={descriptionInput}
|
||||
>
|
||||
{party ? party.description : ''}
|
||||
</textarea>
|
||||
defaultValue={description}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import clonedeep from 'lodash.clonedeep'
|
|||
|
||||
import Alert from '~components/common/Alert'
|
||||
import PartySegmentedControl from '~components/party/PartySegmentedControl'
|
||||
import PartyDetails from '~components/party/PartyDetails'
|
||||
import PartyFooter from '~components/party/PartyFooter'
|
||||
import PartyHeader from '~components/party/PartyHeader'
|
||||
import WeaponGrid from '~components/weapon/WeaponGrid'
|
||||
import SummonGrid from '~components/summon/SummonGrid'
|
||||
|
|
@ -145,37 +145,27 @@ const Party = (props: Props) => {
|
|||
function formatDetailsObject(details: DetailsObject) {
|
||||
const payload: { [key: string]: any } = {}
|
||||
|
||||
const mappings: { [key: string]: string } = {
|
||||
name: 'name',
|
||||
description: 'description',
|
||||
chargeAttack: 'charge_attack',
|
||||
fullAuto: 'full_auto',
|
||||
autoGuard: 'auto_guard',
|
||||
autoSummon: 'auto_summon',
|
||||
clearTime: 'clear_time',
|
||||
buttonCount: 'button_count',
|
||||
chainCount: 'chain_count',
|
||||
turnCount: 'turn_count',
|
||||
extra: 'extra',
|
||||
job: 'job_id',
|
||||
guidebook1_id: 'guidebook1_id',
|
||||
guidebook2_id: 'guidebook2_id',
|
||||
guidebook3_id: 'guidebook3_id',
|
||||
}
|
||||
|
||||
Object.entries(mappings).forEach(([key, value]) => {
|
||||
if (details[key]) {
|
||||
payload[value] = details[key]
|
||||
}
|
||||
})
|
||||
|
||||
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 != undefined)
|
||||
payload.charge_attack = details.chargeAttack
|
||||
if (details.fullAuto != undefined) payload.full_auto = details.fullAuto
|
||||
if (details.autoGuard != undefined) payload.auto_guard = details.autoGuard
|
||||
if (details.autoSummon != undefined)
|
||||
payload.auto_summon = details.autoSummon
|
||||
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 != undefined) payload.extra = details.extra
|
||||
if (details.job) payload.job_id = details.job.id
|
||||
if (details.guidebook1_id) payload.guidebook1_id = details.guidebook1_id
|
||||
if (details.guidebook2_id) payload.guidebook2_id = details.guidebook2_id
|
||||
if (details.guidebook3_id) payload.guidebook3_id = details.guidebook3_id
|
||||
|
||||
if (Object.keys(payload).length >= 1) {
|
||||
return { party: payload }
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
if (Object.keys(payload).length >= 1) return { party: payload }
|
||||
else return {}
|
||||
}
|
||||
|
||||
function cancelAlert() {
|
||||
|
|
@ -275,6 +265,15 @@ const Party = (props: Props) => {
|
|||
appState.party.jobSkills = team.job_skills
|
||||
appState.party.accessory = team.accessory
|
||||
|
||||
appState.party.chargeAttack = team.charge_attack
|
||||
appState.party.fullAuto = team.full_auto
|
||||
appState.party.autoGuard = team.auto_guard
|
||||
appState.party.autoSummon = team.auto_summon
|
||||
appState.party.clearTime = team.clear_time
|
||||
appState.party.buttonCount = team.button_count
|
||||
appState.party.chainCount = team.chain_count
|
||||
appState.party.turnCount = team.turn_count
|
||||
|
||||
appState.party.id = team.id
|
||||
appState.party.shortcode = team.shortcode
|
||||
appState.party.extra = team.extra
|
||||
|
|
@ -455,7 +454,7 @@ const Party = (props: Props) => {
|
|||
|
||||
<section id="Party">{currentGrid()}</section>
|
||||
|
||||
<PartyDetails
|
||||
<PartyFooter
|
||||
party={props.team}
|
||||
new={props.new || false}
|
||||
editable={party.editable}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { subscribe, useSnapshot } from 'valtio'
|
||||
import { Trans, useTranslation } from 'next-i18next'
|
||||
import Link from 'next/link'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import classNames from 'classnames'
|
||||
|
||||
// Dependencies: Common
|
||||
|
|
@ -125,22 +124,27 @@ const PartyDropdown = ({
|
|||
|
||||
// Toasts / Copy URL
|
||||
function handleCopyToastOpenChanged(open: boolean) {
|
||||
setCopyToastOpen(open)
|
||||
setCopyToastOpen(!open)
|
||||
}
|
||||
|
||||
function handleCopyToastCloseClicked() {
|
||||
setCopyToastOpen(false)
|
||||
}
|
||||
|
||||
// Toasts / Remix team
|
||||
// Toasts: Remix team
|
||||
function handleRemixToastOpenChanged(open: boolean) {
|
||||
setRemixToastOpen(open)
|
||||
setRemixToastOpen(!open)
|
||||
}
|
||||
|
||||
function handleRemixToastCloseClicked() {
|
||||
setRemixToastOpen(false)
|
||||
}
|
||||
|
||||
function remixCallback() {
|
||||
setRemixToastOpen(true)
|
||||
remixTeamCallback()
|
||||
}
|
||||
|
||||
const editableItems = () => {
|
||||
return (
|
||||
<>
|
||||
|
|
@ -185,10 +189,23 @@ const PartyDropdown = ({
|
|||
|
||||
<RemixTeamAlert
|
||||
creator={editable}
|
||||
name={partySnapshot.name ? partySnapshot.name : t('no_title')}
|
||||
name={partySnapshot.name || t('no_title')}
|
||||
open={remixAlertOpen}
|
||||
onOpenChange={handleRemixTeamAlertChange}
|
||||
remixCallback={remixTeamCallback}
|
||||
remixCallback={remixCallback}
|
||||
/>
|
||||
|
||||
<RemixedToast
|
||||
open={remixToastOpen}
|
||||
partyName={partySnapshot.name || t('no_title')}
|
||||
onOpenChange={handleRemixToastOpenChanged}
|
||||
onCloseClick={handleRemixToastCloseClicked}
|
||||
/>
|
||||
|
||||
<UrlCopiedToast
|
||||
open={copyToastOpen}
|
||||
onOpenChange={handleCopyToastOpenChanged}
|
||||
onCloseClick={handleCopyToastCloseClicked}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.DetailsWrapper {
|
||||
.FooterWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit-2x;
|
||||
|
|
@ -16,10 +16,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
.PartyDetails {
|
||||
.PartyFooter {
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
line-height: 1.4;
|
||||
white-space: pre-wrap;
|
||||
margin: 0 auto $unit-2x;
|
||||
margin-bottom: $unit-12x;
|
||||
min-height: 10vh;
|
||||
max-width: $unit * 94;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
|
@ -27,11 +30,6 @@
|
|||
@include breakpoint(phone) {
|
||||
padding: 0 $unit;
|
||||
}
|
||||
|
||||
&.Visible {
|
||||
// margin-bottom: $unit-12x;
|
||||
}
|
||||
|
||||
&.Editable {
|
||||
gap: $unit;
|
||||
|
||||
|
|
@ -174,115 +172,109 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.ReadOnly {
|
||||
box-sizing: border-box;
|
||||
line-height: 1.4;
|
||||
white-space: pre-wrap;
|
||||
&.Visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.Visible {
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: $font-regular;
|
||||
line-height: $font-regular * 1.2;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.Details {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: $unit;
|
||||
margin-bottom: $unit-2x;
|
||||
}
|
||||
|
||||
.YoutubeWrapper {
|
||||
background-color: var(--card-bg);
|
||||
border-radius: $card-corner;
|
||||
margin: $unit 0;
|
||||
position: relative;
|
||||
display: block;
|
||||
contain: content;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
cursor: pointer;
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* gradient */
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);
|
||||
background-position: top;
|
||||
background-repeat: repeat-x;
|
||||
height: 60px;
|
||||
padding-bottom: 50px;
|
||||
width: 100%;
|
||||
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: $font-regular;
|
||||
line-height: $font-regular * 1.2;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.Details {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: $unit;
|
||||
margin-bottom: $unit-2x;
|
||||
}
|
||||
|
||||
.YoutubeWrapper {
|
||||
background-color: var(--card-bg);
|
||||
border-radius: $card-corner;
|
||||
margin: $unit 0;
|
||||
position: relative;
|
||||
display: block;
|
||||
contain: content;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
cursor: pointer;
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
|
||||
@include breakpoint(tablet) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* gradient */
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);
|
||||
background-position: top;
|
||||
background-repeat: repeat-x;
|
||||
height: 60px;
|
||||
padding-bottom: 50px;
|
||||
width: 100%;
|
||||
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* responsive iframe with a 16:9 aspect ratio
|
||||
/* responsive iframe with a 16:9 aspect ratio
|
||||
thanks https://css-tricks.com/responsive-iframes/
|
||||
*/
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-bottom: calc(100% / (16 / 9));
|
||||
}
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-bottom: calc(100% / (16 / 9));
|
||||
}
|
||||
|
||||
&:hover > .PlayerButton {
|
||||
opacity: 1;
|
||||
}
|
||||
&:hover > .PlayerButton {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
& > iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
& > iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/* Play button */
|
||||
& > .PlayerButton {
|
||||
background: none;
|
||||
border: none;
|
||||
background-image: url('/icons/youtube.svg');
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
opacity: 0.8;
|
||||
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
/* Play button */
|
||||
& > .PlayerButton {
|
||||
background: none;
|
||||
border: none;
|
||||
background-image: url('/icons/youtube.svg');
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
opacity: 0.8;
|
||||
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
& > .PlayerButton,
|
||||
& > .PlayerButton:before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
}
|
||||
& > .PlayerButton,
|
||||
& > .PlayerButton:before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
}
|
||||
|
||||
/* Post-click styles */
|
||||
&.lyt-activated {
|
||||
cursor: unset;
|
||||
}
|
||||
&.lyt-activated::before,
|
||||
&.lyt-activated > .PlayerButton {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Post-click styles */
|
||||
&.lyt-activated {
|
||||
cursor: unset;
|
||||
}
|
||||
&.lyt-activated::before,
|
||||
&.lyt-activated > .PlayerButton {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import clonedeep from 'lodash.clonedeep'
|
||||
|
||||
|
|
@ -27,10 +28,12 @@ interface Props {
|
|||
updateCallback: (details: DetailsObject) => void
|
||||
}
|
||||
|
||||
const PartyDetails = (props: Props) => {
|
||||
const PartyFooter = (props: Props) => {
|
||||
const { t } = useTranslation('common')
|
||||
const router = useRouter()
|
||||
|
||||
const { party } = useSnapshot(appState)
|
||||
|
||||
const youtubeUrlRegex =
|
||||
/(?:https:\/\/www\.youtube\.com\/watch\?v=|https:\/\/youtu\.be\/)([\w-]+)/g
|
||||
|
||||
|
|
@ -40,16 +43,10 @@ const PartyDetails = (props: Props) => {
|
|||
const [embeddedDescription, setEmbeddedDescription] =
|
||||
useState<React.ReactNode>()
|
||||
|
||||
const readOnlyClasses = classNames({
|
||||
PartyDetails: true,
|
||||
ReadOnly: true,
|
||||
Visible: !open,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// Extract the video IDs from the description
|
||||
if (appState.party.description) {
|
||||
const videoIds = extractYoutubeVideoIds(appState.party.description)
|
||||
if (party.description) {
|
||||
const videoIds = extractYoutubeVideoIds(party.description)
|
||||
|
||||
// Fetch the video titles for each ID
|
||||
const fetchPromises = videoIds.map(({ id }) => fetchYoutubeData(id))
|
||||
|
|
@ -58,7 +55,7 @@ const PartyDetails = (props: Props) => {
|
|||
Promise.all(fetchPromises).then((videoTitles) => {
|
||||
// Replace the video URLs in the description with LiteYoutubeEmbed elements
|
||||
const newDescription = reactStringReplace(
|
||||
appState.party.description,
|
||||
party.description,
|
||||
youtubeUrlRegex,
|
||||
(match, i) => (
|
||||
<LiteYouTubeEmbed
|
||||
|
|
@ -77,7 +74,7 @@ const PartyDetails = (props: Props) => {
|
|||
} else {
|
||||
setEmbeddedDescription('')
|
||||
}
|
||||
}, [appState.party.description])
|
||||
}, [party.description])
|
||||
|
||||
async function fetchYoutubeData(videoId: string) {
|
||||
return await youtube
|
||||
|
|
@ -173,14 +170,6 @@ const PartyDetails = (props: Props) => {
|
|||
})
|
||||
}
|
||||
|
||||
const readOnly = () => {
|
||||
return (
|
||||
<section className={readOnlyClasses}>
|
||||
<Linkify>{embeddedDescription}</Linkify>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
const remixSection = () => {
|
||||
return (
|
||||
<section className="Remixes">
|
||||
|
|
@ -192,10 +181,14 @@ const PartyDetails = (props: Props) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<section className="DetailsWrapper">{readOnly()}</section>
|
||||
<section className="FooterWrapper">
|
||||
<section className="PartyFooter">
|
||||
<Linkify>{embeddedDescription}</Linkify>
|
||||
</section>
|
||||
</section>
|
||||
{remixes && remixes.length > 0 ? remixSection() : ''}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default PartyDetails
|
||||
export default PartyFooter
|
||||
|
|
@ -12,6 +12,7 @@ import Token from '~components/common/Token'
|
|||
import EditPartyModal from '~components/party/EditPartyModal'
|
||||
import PartyDropdown from '~components/party/PartyDropdown'
|
||||
|
||||
import api from '~utils/api'
|
||||
import { accountState } from '~utils/accountState'
|
||||
import { appState, initialAppState } from '~utils/appState'
|
||||
import { formatTimeAgo } from '~utils/timeAgo'
|
||||
|
|
@ -23,7 +24,9 @@ import SaveIcon from '~public/icons/Save.svg'
|
|||
import type { DetailsObject } from 'types'
|
||||
|
||||
import './index.scss'
|
||||
import api from '~utils/api'
|
||||
import RemixTeamAlert from '~components/dialogs/RemixTeamAlert'
|
||||
import RemixedToast from '~components/toasts/RemixedToast'
|
||||
import { set } from 'local-storage'
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
|
|
@ -44,12 +47,16 @@ const PartyHeader = (props: Props) => {
|
|||
|
||||
const { party: partySnapshot } = useSnapshot(appState)
|
||||
|
||||
const [name, setName] = useState('')
|
||||
// State: Component
|
||||
const [remixAlertOpen, setRemixAlertOpen] = useState(false)
|
||||
const [remixToastOpen, setRemixToastOpen] = useState(false)
|
||||
|
||||
// State: Data
|
||||
const [name, setName] = useState('')
|
||||
const [chargeAttack, setChargeAttack] = useState(true)
|
||||
const [fullAuto, setFullAuto] = useState(false)
|
||||
const [autoGuard, setAutoGuard] = useState(false)
|
||||
|
||||
const [autoSummon, setAutoSummon] = useState(false)
|
||||
const [buttonCount, setButtonCount] = useState<number | undefined>(undefined)
|
||||
const [chainCount, setChainCount] = useState<number | undefined>(undefined)
|
||||
const [turnCount, setTurnCount] = useState<number | undefined>(undefined)
|
||||
|
|
@ -78,6 +85,7 @@ const PartyHeader = (props: Props) => {
|
|||
setName(props.party.name)
|
||||
setAutoGuard(props.party.auto_guard)
|
||||
setFullAuto(props.party.full_auto)
|
||||
setAutoSummon(props.party.auto_summon)
|
||||
setChargeAttack(props.party.charge_attack)
|
||||
setClearTime(props.party.clear_time)
|
||||
if (props.party.turn_count) setTurnCount(props.party.turn_count)
|
||||
|
|
@ -155,6 +163,32 @@ const PartyHeader = (props: Props) => {
|
|||
)
|
||||
}
|
||||
|
||||
// Actions: Remix team
|
||||
function remixTeamCallback() {
|
||||
setRemixToastOpen(true)
|
||||
props.remixCallback()
|
||||
}
|
||||
|
||||
// Alerts: Remix team
|
||||
function openRemixTeamAlert() {
|
||||
setRemixAlertOpen(true)
|
||||
}
|
||||
|
||||
function handleRemixTeamAlertChange(open: boolean) {
|
||||
setRemixAlertOpen(open)
|
||||
}
|
||||
|
||||
// Toasts: Remix team
|
||||
function handleRemixToastOpenChanged(open: boolean) {
|
||||
setRemixToastOpen(!open)
|
||||
}
|
||||
|
||||
function handleRemixToastCloseClicked() {
|
||||
setRemixToastOpen(false)
|
||||
}
|
||||
|
||||
// Rendering
|
||||
|
||||
const userBlock = (username?: string, picture?: string, element?: string) => {
|
||||
return (
|
||||
<div className={userClass}>
|
||||
|
|
@ -212,12 +246,12 @@ const PartyHeader = (props: Props) => {
|
|||
<Token
|
||||
className={classNames({
|
||||
ChargeAttack: true,
|
||||
On: chargeAttack,
|
||||
Off: !chargeAttack,
|
||||
On: party.chargeAttack,
|
||||
Off: !party.chargeAttack,
|
||||
})}
|
||||
>
|
||||
{`${t('party.details.labels.charge_attack')} ${
|
||||
chargeAttack ? 'On' : 'Off'
|
||||
party.chargeAttack ? 'On' : 'Off'
|
||||
}`}
|
||||
</Token>
|
||||
)
|
||||
|
|
@ -226,11 +260,13 @@ const PartyHeader = (props: Props) => {
|
|||
<Token
|
||||
className={classNames({
|
||||
FullAuto: true,
|
||||
On: fullAuto,
|
||||
Off: !fullAuto,
|
||||
On: party.fullAuto,
|
||||
Off: !party.fullAuto,
|
||||
})}
|
||||
>
|
||||
{`${t('party.details.labels.full_auto')} ${fullAuto ? 'On' : 'Off'}`}
|
||||
{`${t('party.details.labels.full_auto')} ${
|
||||
party.fullAuto ? 'On' : 'Off'
|
||||
}`}
|
||||
</Token>
|
||||
)
|
||||
|
||||
|
|
@ -238,37 +274,57 @@ const PartyHeader = (props: Props) => {
|
|||
<Token
|
||||
className={classNames({
|
||||
AutoGuard: true,
|
||||
On: autoGuard,
|
||||
Off: !autoGuard,
|
||||
On: party.autoGuard,
|
||||
Off: !party.autoGuard,
|
||||
})}
|
||||
>
|
||||
{`${t('party.details.labels.auto_guard')} ${autoGuard ? 'On' : 'Off'}`}
|
||||
{`${t('party.details.labels.auto_guard')} ${
|
||||
party.autoGuard ? 'On' : 'Off'
|
||||
}`}
|
||||
</Token>
|
||||
)
|
||||
|
||||
const autoSummonToken = (
|
||||
<Token
|
||||
className={classNames({
|
||||
AutoSummon: true,
|
||||
On: party.autoSummon,
|
||||
Off: !party.autoSummon,
|
||||
})}
|
||||
>
|
||||
{`${t('party.details.labels.auto_summon')} ${
|
||||
party.autoSummon ? 'On' : 'Off'
|
||||
}`}
|
||||
</Token>
|
||||
)
|
||||
|
||||
const turnCountToken = (
|
||||
<Token>
|
||||
{t('party.details.turns.with_count', {
|
||||
count: turnCount,
|
||||
count: party.turnCount,
|
||||
})}
|
||||
</Token>
|
||||
)
|
||||
|
||||
const buttonChainToken = () => {
|
||||
if (buttonCount || chainCount) {
|
||||
if (party.buttonCount || party.chainCount) {
|
||||
let string = ''
|
||||
|
||||
if (buttonCount && buttonCount > 0) {
|
||||
string += `${buttonCount}b`
|
||||
if (party.buttonCount && party.buttonCount > 0) {
|
||||
string += `${party.buttonCount}b`
|
||||
}
|
||||
|
||||
if (!buttonCount && chainCount && chainCount > 0) {
|
||||
string += `0${t('party.details.suffix.buttons')}${chainCount}${t(
|
||||
if (!party.buttonCount && party.chainCount && party.chainCount > 0) {
|
||||
string += `0${t('party.details.suffix.buttons')}${party.chainCount}${t(
|
||||
'party.details.suffix.chains'
|
||||
)}`
|
||||
} else if (buttonCount && chainCount && chainCount > 0) {
|
||||
string += `${chainCount}${t('party.details.suffix.chains')}`
|
||||
} else if (buttonCount && !chainCount) {
|
||||
} else if (
|
||||
party.buttonCount &&
|
||||
party.chainCount &&
|
||||
party.chainCount > 0
|
||||
) {
|
||||
string += `${party.chainCount}${t('party.details.suffix.chains')}`
|
||||
} else if (party.buttonCount && !party.chainCount) {
|
||||
string += `0${t('party.details.suffix.chains')}`
|
||||
}
|
||||
|
||||
|
|
@ -277,8 +333,8 @@ const PartyHeader = (props: Props) => {
|
|||
}
|
||||
|
||||
const clearTimeToken = () => {
|
||||
const minutes = Math.floor(clearTime / 60)
|
||||
const seconds = clearTime - minutes * 60
|
||||
const minutes = Math.floor(party.clearTime / 60)
|
||||
const seconds = party.clearTime - minutes * 60
|
||||
|
||||
let string = ''
|
||||
if (minutes > 0)
|
||||
|
|
@ -296,8 +352,9 @@ const PartyHeader = (props: Props) => {
|
|||
{chargeAttackToken}
|
||||
{fullAutoToken}
|
||||
{autoGuardToken}
|
||||
{turnCount ? turnCountToken : ''}
|
||||
{clearTime > 0 ? clearTimeToken() : ''}
|
||||
{autoSummonToken}
|
||||
{party.turnCount ? turnCountToken : ''}
|
||||
{party.clearTime > 0 ? clearTimeToken() : ''}
|
||||
{buttonChainToken()}
|
||||
</section>
|
||||
)
|
||||
|
|
@ -329,7 +386,7 @@ const PartyHeader = (props: Props) => {
|
|||
leftAccessoryIcon={<RemixIcon />}
|
||||
className="Remix"
|
||||
text={t('buttons.remix')}
|
||||
onClick={props.remixCallback}
|
||||
onClick={openRemixTeamAlert}
|
||||
/>
|
||||
</Tooltip>
|
||||
)
|
||||
|
|
@ -341,8 +398,8 @@ const PartyHeader = (props: Props) => {
|
|||
<div className="PartyInfo">
|
||||
<div className="Left">
|
||||
<div className="Header">
|
||||
<h1 className={name ? '' : 'empty'}>
|
||||
{name ? name : t('no_title')}
|
||||
<h1 className={party.name ? '' : 'empty'}>
|
||||
{party.name ? party.name : t('no_title')}
|
||||
</h1>
|
||||
{party.remix && party.sourceParty ? (
|
||||
<Tooltip content={t('tooltips.source')}>
|
||||
|
|
@ -398,6 +455,21 @@ const PartyHeader = (props: Props) => {
|
|||
</div>
|
||||
<section className={classes}>{renderTokens()}</section>
|
||||
</section>
|
||||
|
||||
<RemixTeamAlert
|
||||
creator={props.editable}
|
||||
name={partySnapshot.name ? partySnapshot.name : t('no_title')}
|
||||
open={remixAlertOpen}
|
||||
onOpenChange={handleRemixTeamAlertChange}
|
||||
remixCallback={remixTeamCallback}
|
||||
/>
|
||||
|
||||
<RemixedToast
|
||||
open={remixToastOpen}
|
||||
partyName={props.party?.name || t('no_title')}
|
||||
onOpenChange={handleRemixToastOpenChanged}
|
||||
onCloseClick={handleRemixToastCloseClicked}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
.Combobox.Raid {
|
||||
box-sizing: border-box;
|
||||
min-width: 440px;
|
||||
|
||||
.Header {
|
||||
background: var(--dialog-bg);
|
||||
|
|
@ -184,6 +185,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.SelectTrigger.Raid .Value.Empty {
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.Filters .SelectTrigger.Raid {
|
||||
& > span {
|
||||
overflow: hidden;
|
||||
|
|
|
|||
|
|
@ -105,19 +105,25 @@ const RaidCombobox = (props: Props) => {
|
|||
|
||||
// Set current raid and section when the component mounts
|
||||
useEffect(() => {
|
||||
if (appState.party.raid) {
|
||||
setCurrentRaid(appState.party.raid)
|
||||
setCurrentSection(appState.party.raid.group.section)
|
||||
} else if (props.showAllRaidsOption && !currentRaid) {
|
||||
setCurrentRaid(allRaidsOption)
|
||||
}
|
||||
// if (appState.party.raid) {
|
||||
// setCurrentRaid(appState.party.raid)
|
||||
// if (appState.party.raid.group.section > 0) {
|
||||
// setCurrentSection(appState.party.raid.group.section)
|
||||
// } else {
|
||||
// setCurrentSection(1)
|
||||
// }
|
||||
// } else if (props.showAllRaidsOption && !currentRaid) {
|
||||
// setCurrentRaid(allRaidsOption)
|
||||
// }
|
||||
}, [])
|
||||
|
||||
// Set current raid and section when the current raid changes
|
||||
useEffect(() => {
|
||||
if (props.currentRaid) {
|
||||
setCurrentRaid(props.currentRaid)
|
||||
setCurrentSection(props.currentRaid.group.section)
|
||||
if (appState.party.raid && appState.party.raid.group.section > 0)
|
||||
setCurrentSection(props.currentRaid.group.section)
|
||||
else setCurrentSection(1)
|
||||
}
|
||||
}, [props.currentRaid])
|
||||
|
||||
|
|
@ -260,7 +266,11 @@ const RaidCombobox = (props: Props) => {
|
|||
// Toggle the open state of the combobox
|
||||
function toggleOpen() {
|
||||
if (open) {
|
||||
if (currentRaid && currentRaid.slug !== 'all') {
|
||||
if (
|
||||
currentRaid &&
|
||||
currentRaid.slug !== 'all' &&
|
||||
currentRaid.group.section > 0
|
||||
) {
|
||||
setCurrentSection(currentRaid.group.section)
|
||||
}
|
||||
setScrolled(false)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import React from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import Toast from '~components/common/Toast'
|
||||
import { Trans, useTranslation } from 'next-i18next'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
partyName: string
|
||||
open: boolean
|
||||
|
|
@ -19,7 +17,9 @@ const RemixedToast = ({
|
|||
onCloseClick,
|
||||
}: Props) => {
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
useEffect(() => {
|
||||
console.log(partyName)
|
||||
}, [])
|
||||
// Methods: Event handlers
|
||||
function handleOpenChange() {
|
||||
onOpenChange(open)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import React from 'react'
|
||||
import Toast from '~components/common/Toast'
|
||||
|
||||
import './index.scss'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
interface Props {
|
||||
|
|
|
|||
|
|
@ -394,12 +394,14 @@ const WeaponModal = ({
|
|||
{gridWeapon.object.awakenings ? awakeningSelect() : ''}
|
||||
</div>
|
||||
<div className="DialogFooter" ref={footerRef}>
|
||||
<Button
|
||||
contained={true}
|
||||
onClick={updateWeapon}
|
||||
disabled={!formValid}
|
||||
text={t('modals.weapon.buttons.confirm')}
|
||||
/>
|
||||
<div className="actions">
|
||||
<Button
|
||||
contained={true}
|
||||
onClick={updateWeapon}
|
||||
disabled={!formValid}
|
||||
text={t('modals.weapon.buttons.confirm')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@
|
|||
"unauthorized": "You don't have permission to perform that action"
|
||||
},
|
||||
"filters": {
|
||||
"name": "Filter",
|
||||
"labels": {
|
||||
"element": "Element",
|
||||
"series": "Series",
|
||||
|
|
@ -383,6 +384,7 @@
|
|||
"charge_attack": "Charge Attack",
|
||||
"full_auto": "Full Auto",
|
||||
"auto_guard": "Auto Guard",
|
||||
"auto_summon": "Auto Summon",
|
||||
"turn_count": "Turn count",
|
||||
"button_chain": "Buttons/Chains",
|
||||
"clear_time": "Clear time"
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@
|
|||
"unauthorized": "行ったアクションを実行する権限がありません"
|
||||
},
|
||||
"filters": {
|
||||
"name": "フィルター",
|
||||
"labels": {
|
||||
"element": "属性",
|
||||
"series": "シリーズ",
|
||||
|
|
@ -380,6 +381,7 @@
|
|||
"charge_attack": "奥義",
|
||||
"full_auto": "フルオート",
|
||||
"auto_guard": "オートガード",
|
||||
"auto_summon": "オート召喚",
|
||||
"turn_count": "経過ターン",
|
||||
"button_chain": "ポチチェイン",
|
||||
"clear_time": "討伐時間"
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ interface AppState {
|
|||
element: number
|
||||
fullAuto: boolean
|
||||
autoGuard: boolean
|
||||
autoSummon: boolean
|
||||
chargeAttack: boolean
|
||||
clearTime: number
|
||||
buttonCount?: number
|
||||
|
|
@ -110,6 +111,7 @@ export const initialAppState: AppState = {
|
|||
raid: undefined,
|
||||
fullAuto: false,
|
||||
autoGuard: false,
|
||||
autoSummon: false,
|
||||
chargeAttack: true,
|
||||
clearTime: 0,
|
||||
buttonCount: undefined,
|
||||
|
|
|
|||
Loading…
Reference in a new issue