|
|
@ -340,240 +340,249 @@ export default function CharacterDetailDialog({ |
|
|
<aside className="character_detail_dialog__right"> |
|
|
<aside className="character_detail_dialog__right"> |
|
|
<div className="character_detail_dialog__rightColumn"> |
|
|
<div className="character_detail_dialog__rightColumn"> |
|
|
<div className="character_detail_dialog__mainContent"> |
|
|
<div className="character_detail_dialog__mainContent"> |
|
|
<div className="character_detail_dialog__authorRow"> |
|
|
<div className="character_detail_dialog__authorRow"> |
|
|
{characterDetail.userInfo && isUserUploadCharacter ? ( |
|
|
{characterDetail.userInfo && isUserUploadCharacter ? ( |
|
|
<div className="character_detail_dialog__authorInfo"> |
|
|
<div className="character_detail_dialog__authorInfo"> |
|
|
<img className="character_detail_dialog__authorAvatar" src={characterDetail.userInfo.avatar} alt="" /> |
|
|
<img className="character_detail_dialog__authorAvatar" src={characterDetail.userInfo.avatar} alt="" /> |
|
|
<p className="character_detail_dialog__authorName">{characterDetail.userInfo.name}</p> |
|
|
<p className="character_detail_dialog__authorName">{characterDetail.userInfo.name}</p> |
|
|
{!characterDetail.userInfo.userFollowed ? ( |
|
|
{!characterDetail.userInfo.userFollowed ? ( |
|
|
<button type="button" className="character_detail_dialog__authorFollowBtn" onClick={() => addFollow(characterDetail.userInfo.id)}> |
|
|
<button type="button" className="character_detail_dialog__authorFollowBtn" onClick={() => addFollow(characterDetail.userInfo.id)}> |
|
|
+{t("pages.profile.stats.following")} |
|
|
+{t("pages.profile.stats.following")} |
|
|
</button> |
|
|
</button> |
|
|
|
|
|
) : ( |
|
|
|
|
|
<button |
|
|
|
|
|
type="button" |
|
|
|
|
|
className="character_detail_dialog__authorFollowBtn character_detail_dialog__authorFollowBtn_active" |
|
|
|
|
|
onClick={() => delFollow(characterDetail.userInfo.userId)} |
|
|
|
|
|
> |
|
|
|
|
|
{t("pages.charactersCreate.followed")} |
|
|
|
|
|
</button> |
|
|
|
|
|
)} |
|
|
|
|
|
</div> |
|
|
|
|
|
) : !isUserUploadCharacter && characterDetail?.id != null && characterDetail.id !== "" ? ( |
|
|
|
|
|
<div className="character_detail_dialog__authorInfo"> |
|
|
|
|
|
<img |
|
|
|
|
|
className="character_detail_dialog__authorAvatar" |
|
|
|
|
|
src={new URL("/src/assets/images/popi_avatar.png", import.meta.url).href} |
|
|
|
|
|
alt="" |
|
|
|
|
|
/> |
|
|
|
|
|
<p className="character_detail_dialog__authorName">Popi</p> |
|
|
|
|
|
</div> |
|
|
) : ( |
|
|
) : ( |
|
|
<button |
|
|
<div /> |
|
|
type="button" |
|
|
|
|
|
className="character_detail_dialog__authorFollowBtn character_detail_dialog__authorFollowBtn_active" |
|
|
|
|
|
onClick={() => delFollow(characterDetail.userInfo.userId)} |
|
|
|
|
|
> |
|
|
|
|
|
{t("pages.charactersCreate.followed")} |
|
|
|
|
|
</button> |
|
|
|
|
|
)} |
|
|
)} |
|
|
</div> |
|
|
<div className="character_detail_dialog__authorActions"> |
|
|
) : ( |
|
|
<button type="button" className="character_detail_dialog__likeRow" onClick={() => { toggleLike() }}> |
|
|
<div /> |
|
|
<img src={new URL(`/src/assets/images/${characterDetail.userLiked ? "ic_like_active" : "ic_like"}.png`, import.meta.url).href} alt="" /> |
|
|
)} |
|
|
{characterDetail.likeNum || 0} |
|
|
<div className="character_detail_dialog__authorActions"> |
|
|
</button> |
|
|
<button type="button" className="character_detail_dialog__likeRow" onClick={() => { toggleLike() }}> |
|
|
<Dropdown |
|
|
<img src={new URL(`/src/assets/images/${characterDetail.userLiked ? "ic_like_active" : "ic_like"}.png`, import.meta.url).href} alt="" /> |
|
|
trigger="click" |
|
|
{characterDetail.likeNum || 0} |
|
|
position="bl" |
|
|
</button> |
|
|
popupVisible={railMenuOpen} |
|
|
<Dropdown |
|
|
onVisibleChange={setRailMenuOpen} |
|
|
trigger="click" |
|
|
droplist={ |
|
|
position="bl" |
|
|
<div id="character-details-rail-menu" className="character_detail_dialog__floatMenu" role="menu" aria-label={t("character_detail.download")}> |
|
|
popupVisible={railMenuOpen} |
|
|
<button type="button" className="character_detail_dialog__floatRow" role="menuitem" onClick={handleDownload}> |
|
|
onVisibleChange={setRailMenuOpen} |
|
|
<img className="character_detail_dialog__floatRowIcon" src={new URL("/src/assets/images/ic_download.png", import.meta.url).href} alt="" /> |
|
|
droplist={ |
|
|
{t("character_detail.download")} |
|
|
<div id="character-details-rail-menu" className="character_detail_dialog__floatMenu" role="menu" aria-label={t("character_detail.download")}> |
|
|
</button> |
|
|
<button type="button" className="character_detail_dialog__floatRow" role="menuitem" onClick={handleDownload}> |
|
|
{isUserUploadCharacter && isOwnCharacter ? ( |
|
|
<img className="character_detail_dialog__floatRowIcon" src={new URL("/src/assets/images/ic_download.png", import.meta.url).href} alt="" /> |
|
|
<button type="button" className="character_detail_dialog__floatRow" role="menuitem" onClick={handleDeleteCharacter}> |
|
|
{t("character_detail.download")} |
|
|
<img className="character_detail_dialog__floatRowIcon" src={new URL("/src/assets/images/ic_delete.png", import.meta.url).href} alt="" /> |
|
|
|
|
|
{t("pages.assetDetails.delete")} |
|
|
|
|
|
</button> |
|
|
|
|
|
) : null} |
|
|
|
|
|
</div> |
|
|
|
|
|
} |
|
|
|
|
|
> |
|
|
|
|
|
<button |
|
|
|
|
|
type="button" |
|
|
|
|
|
className="character_detail_dialog__moreBtn" |
|
|
|
|
|
aria-label={t("character_detail.download")} |
|
|
|
|
|
aria-haspopup="menu" |
|
|
|
|
|
aria-expanded={railMenuOpen} |
|
|
|
|
|
aria-controls="character-details-rail-menu" |
|
|
|
|
|
> |
|
|
|
|
|
<img src={new URL("/src/assets/images/ic_more.png", import.meta.url).href} alt="" /> |
|
|
</button> |
|
|
</button> |
|
|
{isUserUploadCharacter && isOwnCharacter ? ( |
|
|
</Dropdown> |
|
|
<button type="button" className="character_detail_dialog__floatRow" role="menuitem" onClick={handleDeleteCharacter}> |
|
|
</div> |
|
|
<img className="character_detail_dialog__floatRowIcon" src={new URL("/src/assets/images/ic_delete.png", import.meta.url).href} alt="" /> |
|
|
</div> |
|
|
{t("pages.assetDetails.delete")} |
|
|
|
|
|
</button> |
|
|
|
|
|
) : null} |
|
|
|
|
|
</div> |
|
|
|
|
|
} |
|
|
|
|
|
> |
|
|
|
|
|
<button |
|
|
|
|
|
type="button" |
|
|
|
|
|
className="character_detail_dialog__moreBtn" |
|
|
|
|
|
aria-label={t("character_detail.download")} |
|
|
|
|
|
aria-haspopup="menu" |
|
|
|
|
|
aria-expanded={railMenuOpen} |
|
|
|
|
|
aria-controls="character-details-rail-menu" |
|
|
|
|
|
> |
|
|
|
|
|
<img src={new URL("/src/assets/images/ic_more.png", import.meta.url).href} alt="" /> |
|
|
|
|
|
</button> |
|
|
|
|
|
</Dropdown> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div className="character_detail_dialog__metaHintRow"> |
|
|
<div className="character_detail_dialog__metaHintRow"> |
|
|
<span className="character_detail_dialog__metaHintText">{formatLocalDate(characterDetail.createTime ?? characterDetail.taskInfo?.createTime)}</span> |
|
|
<span className="character_detail_dialog__metaHintText">{formatLocalDate(characterDetail.createTime ?? characterDetail.taskInfo?.createTime)}</span> |
|
|
<span className="character_detail_dialog__metaHintDivider" /> |
|
|
<span className="character_detail_dialog__metaHintDivider" /> |
|
|
<span className="character_detail_dialog__metaHintText">内容由AI生成</span> |
|
|
<span className="character_detail_dialog__metaHintText">内容由AI生成</span> |
|
|
</div> |
|
|
</div> |
|
|
<div className="character_detail_dialog__divider" role="presentation" /> |
|
|
<div className="character_detail_dialog__divider" role="presentation" /> |
|
|
|
|
|
|
|
|
<div className="character_detail_dialog__avatarSection"> |
|
|
<div className="character_detail_dialog__avatarSection"> |
|
|
<div className="character_detail_dialog__avatarPreview"> |
|
|
<div className="character_detail_dialog__avatarPreview"> |
|
|
<img className="character_detail_dialog__avatarPreviewImage" src={characterDetail.avatar || characterDetail.headImage || characterDetail.threeViewImage} alt="" /> |
|
|
<img className="character_detail_dialog__avatarPreviewImage" src={characterDetail.avatar || characterDetail.headImage || characterDetail.threeViewImage} alt="" /> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
{false && isOwnCharacter && isUserUploadCharacter && ( |
|
|
{false && isOwnCharacter && isUserUploadCharacter && ( |
|
|
<div className="character_detail_dialog__avatarUpdate"> |
|
|
<div className="character_detail_dialog__avatarUpdate"> |
|
|
<button type="button" className="character_detail_dialog__avatarUpdateBtn" onClick={handleOpenAvatarCrop}> |
|
|
<button type="button" className="character_detail_dialog__avatarUpdateBtn" onClick={handleOpenAvatarCrop}> |
|
|
修改头像 |
|
|
修改头像 |
|
|
</button> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
)} |
|
|
|
|
|
|
|
|
|
|
|
<div className="character_detail_dialog__nameRow"> |
|
|
|
|
|
<div className="character_detail_dialog__nameValue"> |
|
|
|
|
|
{!isEditingCharacterName ? ( |
|
|
|
|
|
<> |
|
|
|
|
|
<div className="character_detail_dialog__nameValueText">{characterDetail.title}</div> |
|
|
|
|
|
{isOwnCharacter && <img |
|
|
|
|
|
className="character_detail_dialog__edit" |
|
|
|
|
|
src={new URL("/src/assets/images/ic_character_edit.png", import.meta.url).href} |
|
|
|
|
|
alt="" |
|
|
|
|
|
onClick={handleStartEditName} |
|
|
|
|
|
/>} |
|
|
|
|
|
</> |
|
|
|
|
|
) : ( |
|
|
|
|
|
<div className="character_detail_dialog__nameEditField"> |
|
|
|
|
|
<Input |
|
|
|
|
|
autoFocus |
|
|
|
|
|
className="character_detail_dialog__nameInput" |
|
|
|
|
|
style={{ width: `${characterNameInputWidth}px` }} |
|
|
|
|
|
value={characterName} |
|
|
|
|
|
onChange={setCharacterName} |
|
|
|
|
|
onFocus={(event) => placeCaretAtEnd(event.target)} |
|
|
|
|
|
onBlur={() => { |
|
|
|
|
|
if (skipNextNameBlurRef.current) { |
|
|
|
|
|
skipNextNameBlurRef.current = false; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
void handleFinishEditName(); |
|
|
|
|
|
}} |
|
|
|
|
|
onPressEnter={() => { void handleFinishEditName(); }} |
|
|
|
|
|
onKeyDown={(event) => { |
|
|
|
|
|
if (event.key === "Escape") { |
|
|
|
|
|
skipNextNameBlurRef.current = true; |
|
|
|
|
|
handleCancelEditName(); |
|
|
|
|
|
} |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
)} |
|
|
)} |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div className="character_detail_dialog__intro"> |
|
|
<div className="character_detail_dialog__nameRow"> |
|
|
<p className="character_detail_dialog__introTitle">{t("character_detail.role_intro_title")}</p> |
|
|
<div className="character_detail_dialog__nameValue"> |
|
|
<div className="character_detail_dialog__introBody"> |
|
|
{!isEditingCharacterName ? ( |
|
|
{!isEditingDescription ? ( |
|
|
<> |
|
|
<> |
|
|
<div className="character_detail_dialog__nameValueText">{characterDetail.title}</div> |
|
|
<p className="character_detail_dialog__introText">{characterDetail.description}</p> |
|
|
{isOwnCharacter && <img |
|
|
{isOwnCharacter && <img |
|
|
className="character_detail_dialog__edit" |
|
|
className="character_detail_dialog__edit" |
|
|
src={new URL("/src/assets/images/ic_character_edit.png", import.meta.url).href} |
|
|
src={new URL("/src/assets/images/ic_character_edit.png", import.meta.url).href} |
|
|
alt="" |
|
|
alt="" |
|
|
onClick={handleStartEditName} |
|
|
onClick={handleStartEditIntro} |
|
|
/>} |
|
|
/>} |
|
|
</> |
|
|
</> |
|
|
) : ( |
|
|
) : ( |
|
|
<div className="character_detail_dialog__nameEditField"> |
|
|
<Input.TextArea |
|
|
<Input |
|
|
autoFocus |
|
|
autoFocus |
|
|
className="character_detail_dialog__introInput" |
|
|
className="character_detail_dialog__nameInput" |
|
|
value={description} |
|
|
style={{ width: `${characterNameInputWidth}px` }} |
|
|
onChange={setDescription} |
|
|
value={characterName} |
|
|
onFocus={(event) => placeCaretAtEnd(event.target)} |
|
|
onChange={setCharacterName} |
|
|
onBlur={() => { |
|
|
onFocus={(event) => placeCaretAtEnd(event.target)} |
|
|
if (skipNextIntroBlurRef.current) { |
|
|
onBlur={() => { |
|
|
skipNextIntroBlurRef.current = false; |
|
|
if (skipNextNameBlurRef.current) { |
|
|
return; |
|
|
skipNextNameBlurRef.current = false; |
|
|
} |
|
|
return; |
|
|
void handleFinishEditIntro(); |
|
|
} |
|
|
}} |
|
|
void handleFinishEditName(); |
|
|
autoSize={{ minRows: 3, maxRows: 8 }} |
|
|
}} |
|
|
onKeyDown={(event) => { |
|
|
onPressEnter={() => { void handleFinishEditName(); }} |
|
|
if (event.key === "Escape") { |
|
|
onKeyDown={(event) => { |
|
|
skipNextIntroBlurRef.current = true; |
|
|
if (event.key === "Escape") { |
|
|
handleCancelEditIntro(); |
|
|
skipNextNameBlurRef.current = true; |
|
|
} |
|
|
handleCancelEditName(); |
|
|
if ((event.metaKey || event.ctrlKey) && event.key === "Enter") void handleFinishEditIntro(); |
|
|
} |
|
|
}} |
|
|
}} |
|
|
/> |
|
|
/> |
|
|
|
|
|
</div> |
|
|
|
|
|
)} |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div className="character_detail_dialog__intro"> |
|
|
|
|
|
<p className="character_detail_dialog__introTitle">{t("character_detail.role_intro_title")}</p> |
|
|
|
|
|
<div className="character_detail_dialog__introBody"> |
|
|
|
|
|
{!isEditingDescription ? ( |
|
|
|
|
|
<> |
|
|
|
|
|
<p className="character_detail_dialog__introText">{characterDetail.description}</p> |
|
|
|
|
|
{isOwnCharacter && <img |
|
|
|
|
|
className="character_detail_dialog__edit" |
|
|
|
|
|
src={new URL("/src/assets/images/ic_character_edit.png", import.meta.url).href} |
|
|
|
|
|
alt="" |
|
|
|
|
|
onClick={handleStartEditIntro} |
|
|
|
|
|
/>} |
|
|
|
|
|
</> |
|
|
|
|
|
) : ( |
|
|
|
|
|
<Input.TextArea |
|
|
|
|
|
autoFocus |
|
|
|
|
|
className="character_detail_dialog__introInput" |
|
|
|
|
|
value={description} |
|
|
|
|
|
onChange={setDescription} |
|
|
|
|
|
onFocus={(event) => placeCaretAtEnd(event.target)} |
|
|
|
|
|
onBlur={() => { |
|
|
|
|
|
if (skipNextIntroBlurRef.current) { |
|
|
|
|
|
skipNextIntroBlurRef.current = false; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
void handleFinishEditIntro(); |
|
|
|
|
|
}} |
|
|
|
|
|
autoSize={{ minRows: 3, maxRows: 8 }} |
|
|
|
|
|
onKeyDown={(event) => { |
|
|
|
|
|
if (event.key === "Escape") { |
|
|
|
|
|
skipNextIntroBlurRef.current = true; |
|
|
|
|
|
handleCancelEditIntro(); |
|
|
|
|
|
} |
|
|
|
|
|
if ((event.metaKey || event.ctrlKey) && event.key === "Enter") void handleFinishEditIntro(); |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
|
|
|
)} |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
{isOwnCharacter && ( |
|
|
|
|
|
<div className="character_detail_dialog__toggleRow"> |
|
|
|
|
|
<span className="character_detail_dialog__toggleLabel">{t("pages.charactersCreate.createRoleModal.publicDisplay")}</span> |
|
|
|
|
|
<button |
|
|
|
|
|
type="button" |
|
|
|
|
|
className="character_detail_dialog__toggleStatus" |
|
|
|
|
|
onClick={handleTogglePublic} |
|
|
|
|
|
aria-label={t("pages.charactersCreate.createRoleModal.publicDisplaySwitchAria")} |
|
|
|
|
|
aria-pressed={isPublic} |
|
|
|
|
|
> |
|
|
|
|
|
<span className={`character_detail_dialog__toggleStatusPart${isPublic ? " character_detail_dialog__toggleStatusPart_active" : ""}`}>公开</span> |
|
|
|
|
|
<span className="character_detail_dialog__toggleStatusSlash"> / </span> |
|
|
|
|
|
<span className={`character_detail_dialog__toggleStatusPart${!isPublic ? " character_detail_dialog__toggleStatusPart_active" : ""}`}>未公开</span> |
|
|
|
|
|
</button> |
|
|
|
|
|
</div> |
|
|
)} |
|
|
)} |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
{isOwnCharacter && ( |
|
|
{characterDetail.taskInfo != null && ( |
|
|
<div className="character_detail_dialog__toggleRow"> |
|
|
<div className="character_detail_dialog__taskInlineMeta"> |
|
|
<span className="character_detail_dialog__toggleLabel">{t("pages.charactersCreate.createRoleModal.publicDisplay")}</span> |
|
|
<span className="character_detail_dialog__taskInlineMetaItem">{characterDetail.taskInfo?.aiModelName ?? ""}</span> |
|
|
<button |
|
|
<span className="character_detail_dialog__taskInlineMetaDivider" /> |
|
|
type="button" |
|
|
<span className="character_detail_dialog__taskInlineMetaItem"> |
|
|
className="character_detail_dialog__toggleStatus" |
|
|
{characterDetail.taskInfo?.width && characterDetail.taskInfo?.height |
|
|
onClick={handleTogglePublic} |
|
|
? `${characterDetail.taskInfo.width}P` |
|
|
aria-label={t("pages.charactersCreate.createRoleModal.publicDisplaySwitchAria")} |
|
|
: ""} |
|
|
aria-pressed={isPublic} |
|
|
</span> |
|
|
> |
|
|
<span className="character_detail_dialog__taskInlineMetaDivider" /> |
|
|
<span className={`character_detail_dialog__toggleStatusPart${isPublic ? " character_detail_dialog__toggleStatusPart_active" : ""}`}>公开</span> |
|
|
<span className="character_detail_dialog__taskInlineMetaItem">{characterDetail.taskInfo?.aspectRatio ?? ""}</span> |
|
|
<span className="character_detail_dialog__toggleStatusSlash"> / </span> |
|
|
<span className="character_detail_dialog__taskInlineMetaDivider" /> |
|
|
<span className={`character_detail_dialog__toggleStatusPart${!isPublic ? " character_detail_dialog__toggleStatusPart_active" : ""}`}>未公开</span> |
|
|
<span className="character_detail_dialog__taskInlineMetaItem">详细信息</span> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
)} |
|
|
)} |
|
|
|
|
|
|
|
|
|
|
|
{characterDetail.taskInfo != null && ( |
|
|
|
|
|
<div className="character_detail_dialog__taskInlineMeta"> |
|
|
|
|
|
<span className="character_detail_dialog__taskInlineMetaItem">{characterDetail.taskInfo?.aiModelName ?? ""}</span> |
|
|
|
|
|
<span className="character_detail_dialog__taskInlineMetaDivider" /> |
|
|
|
|
|
<span className="character_detail_dialog__taskInlineMetaItem"> |
|
|
|
|
|
{characterDetail.taskInfo?.width && characterDetail.taskInfo?.height |
|
|
|
|
|
? `${characterDetail.taskInfo.width}P` |
|
|
|
|
|
: ""} |
|
|
|
|
|
</span> |
|
|
|
|
|
<span className="character_detail_dialog__taskInlineMetaDivider" /> |
|
|
|
|
|
<span className="character_detail_dialog__taskInlineMetaItem">{characterDetail.taskInfo?.aspectRatio ?? ""}</span> |
|
|
|
|
|
<span className="character_detail_dialog__taskInlineMetaDivider" /> |
|
|
|
|
|
<span className="character_detail_dialog__taskInlineMetaItem">详细信息</span> |
|
|
|
|
|
</div> |
|
|
|
|
|
)} |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div className="character_detail_dialog__sidebarFoot"> |
|
|
<div className="character_detail_dialog__sidebarFoot"> |
|
|
<div className="character_detail_dialog__actionPanel character_detail_dialog__actionPanel_prompt"> |
|
|
<div className="character_detail_dialog__actionPanel character_detail_dialog__actionPanel_prompt"> |
|
|
{promptQuickActions.map((label) => ( |
|
|
{promptQuickActions.map((label) => ( |
|
|
<button key={label} type="button" className="character_detail_dialog__panelActionBtn"> |
|
|
<button key={label} type="button" className="character_detail_dialog__panelActionBtn"> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionText">{label}</span> |
|
|
|
|
|
</button> |
|
|
|
|
|
))} |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className="character_detail_dialog__actionPanel character_detail_dialog__actionPanel_media"> |
|
|
|
|
|
{mediaActions.map((label) => ( |
|
|
|
|
|
<button key={label} type="button" className="character_detail_dialog__panelActionBtn"> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionText">{label}</span> |
|
|
|
|
|
</button> |
|
|
|
|
|
))} |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className="character_detail_dialog__actionPanel character_detail_dialog__actionPanel_primary"> |
|
|
|
|
|
<div |
|
|
|
|
|
className="character_detail_dialog__panelActionBtn character_detail_dialog__panelActionBtn_active" |
|
|
|
|
|
onClick={() => { |
|
|
|
|
|
const refImage = String(characterDetail?.threeViewImage ?? "").trim(); |
|
|
|
|
|
const refTitle = String(characterDetail?.title ?? "").trim(); |
|
|
|
|
|
if (!refImage) return; |
|
|
|
|
|
requestAppendImageUrl(refImage, refTitle, 103); |
|
|
|
|
|
onClose?.(); |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
<span className="character_detail_dialog__panelActionText">{label}</span> |
|
|
<span className="character_detail_dialog__panelActionText">{t("character_detail.use_character")}</span> |
|
|
</button> |
|
|
</div> |
|
|
))} |
|
|
<button type="button" className="character_detail_dialog__panelActionBtn" onClick={onUseCharacter}> |
|
|
</div> |
|
|
|
|
|
<div className="character_detail_dialog__actionPanel character_detail_dialog__actionPanel_media"> |
|
|
|
|
|
{mediaActions.map((label) => ( |
|
|
|
|
|
<button key={label} type="button" className="character_detail_dialog__panelActionBtn"> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
<span className="character_detail_dialog__panelActionText">{label}</span> |
|
|
<span className="character_detail_dialog__panelActionText">做同款</span> |
|
|
</button> |
|
|
</button> |
|
|
))} |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className="character_detail_dialog__actionPanel character_detail_dialog__actionPanel_primary"> |
|
|
|
|
|
<div |
|
|
|
|
|
className="character_detail_dialog__panelActionBtn character_detail_dialog__panelActionBtn_active" |
|
|
|
|
|
onClick={() => { |
|
|
|
|
|
const refImage = String(characterDetail?.threeViewImage ?? "").trim(); |
|
|
|
|
|
const refTitle = String(characterDetail?.title ?? "").trim(); |
|
|
|
|
|
if (!refImage) return; |
|
|
|
|
|
requestAppendImageUrl(refImage, refTitle, 103); |
|
|
|
|
|
onClose?.(); |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionText">{t("character_detail.use_character")}</span> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
<button type="button" className="character_detail_dialog__panelActionBtn" onClick={onUseCharacter}> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionIcon" /> |
|
|
|
|
|
<span className="character_detail_dialog__panelActionText">做同款</span> |
|
|
|
|
|
</button> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</aside> |
|
|
</aside> |
|
|
</div> |
|
|
</div> |
|
|
<AvatarCropModal |
|
|
<AvatarCropModal |
|
|
|