@houser/edus-plugin 1.0.9 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/lib/client.js +1377 -1294
- package/lib/types/client/LoginGuide.d.ts +2 -1
- package/lib/types/client/MyWorksPanel.d.ts +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -20836,1308 +20836,1345 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
20836
20836
|
});
|
|
20837
20837
|
}
|
|
20838
20838
|
//#endregion
|
|
20839
|
-
//#region lib/types/client/
|
|
20840
|
-
|
|
20841
|
-
|
|
20842
|
-
|
|
20843
|
-
|
|
20844
|
-
|
|
20845
|
-
|
|
20846
|
-
|
|
20847
|
-
|
|
20848
|
-
|
|
20849
|
-
|
|
20850
|
-
|
|
20851
|
-
|
|
20852
|
-
|
|
20853
|
-
|
|
20854
|
-
|
|
20839
|
+
//#region lib/types/client/LoginGuide.js
|
|
20840
|
+
/**
|
|
20841
|
+
* 对话模型必须登录课成账号才能用(网关以登录 token 鉴权计费),而 Harness 自带
|
|
20842
|
+
* 的账号与模型设置入口都已屏蔽,所以登录引导由本插件提供:
|
|
20843
|
+
*
|
|
20844
|
+
* - 全局登录弹窗(shell.overlay):未登录启动时自动弹出一次,可点右上角关闭;
|
|
20845
|
+
* - 输入框上方横幅(conversation.input.dock):会话内未登录时常驻;
|
|
20846
|
+
* - 侧边栏底部按钮(sidebar.footer.action):新会话页也能找到登录入口。
|
|
20847
|
+
*
|
|
20848
|
+
* 三处共用一个弹窗开关,登录成功后弹窗关闭、横幅消失;侧边栏按钮转为显示当前
|
|
20849
|
+
* 账号,点击打开账号信息弹窗(AccountDialogOverlay)。
|
|
20850
|
+
*/
|
|
20851
|
+
let dialogOpen = false;
|
|
20852
|
+
/** 打开弹窗时附带的提示(如「登录状态已失效」),关闭时清空。 */
|
|
20853
|
+
let dialogNotice = "";
|
|
20854
|
+
const dialogListeners = /* @__PURE__ */ new Set();
|
|
20855
|
+
function setDialogOpen(next, notice = "") {
|
|
20856
|
+
if (dialogOpen === next && dialogNotice === notice) return;
|
|
20857
|
+
dialogOpen = next;
|
|
20858
|
+
dialogNotice = notice;
|
|
20859
|
+
for (const listener of dialogListeners) listener();
|
|
20855
20860
|
}
|
|
20856
|
-
|
|
20857
|
-
|
|
20858
|
-
|
|
20859
|
-
const styles$1 = {
|
|
20860
|
-
root: {
|
|
20861
|
-
display: "flex",
|
|
20862
|
-
flexDirection: "column",
|
|
20863
|
-
height: "100%",
|
|
20864
|
-
minHeight: 0,
|
|
20865
|
-
background: "var(--dsw-alias-bg-base)"
|
|
20861
|
+
const EdusLoginDialog = {
|
|
20862
|
+
open(notice) {
|
|
20863
|
+
setDialogOpen(true, typeof notice === "string" ? notice : "");
|
|
20866
20864
|
},
|
|
20867
|
-
|
|
20868
|
-
|
|
20869
|
-
alignItems: "center",
|
|
20870
|
-
gap: 7,
|
|
20871
|
-
padding: "7px 10px",
|
|
20872
|
-
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
20873
|
-
background: "var(--dsw-alias-bg-layer-1)"
|
|
20865
|
+
close() {
|
|
20866
|
+
setDialogOpen(false);
|
|
20874
20867
|
},
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
|
|
20878
|
-
|
|
20879
|
-
|
|
20880
|
-
|
|
20881
|
-
font: "inherit",
|
|
20882
|
-
fontSize: 12,
|
|
20883
|
-
cursor: "pointer"
|
|
20868
|
+
notice: () => dialogNotice,
|
|
20869
|
+
subscribe(listener) {
|
|
20870
|
+
dialogListeners.add(listener);
|
|
20871
|
+
return () => {
|
|
20872
|
+
dialogListeners.delete(listener);
|
|
20873
|
+
};
|
|
20884
20874
|
},
|
|
20885
|
-
|
|
20886
|
-
|
|
20887
|
-
|
|
20888
|
-
|
|
20889
|
-
|
|
20890
|
-
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20894
|
-
|
|
20875
|
+
getSnapshot: () => dialogOpen
|
|
20876
|
+
};
|
|
20877
|
+
function useDialogOpen() {
|
|
20878
|
+
return (0, react.useSyncExternalStore)(EdusLoginDialog.subscribe, EdusLoginDialog.getSnapshot, () => false);
|
|
20879
|
+
}
|
|
20880
|
+
/** 账号信息弹窗的开关,与登录弹窗相互独立。 */
|
|
20881
|
+
let accountOpen = false;
|
|
20882
|
+
const accountListeners = /* @__PURE__ */ new Set();
|
|
20883
|
+
function setAccountOpen(next) {
|
|
20884
|
+
if (accountOpen === next) return;
|
|
20885
|
+
accountOpen = next;
|
|
20886
|
+
for (const listener of accountListeners) listener();
|
|
20887
|
+
}
|
|
20888
|
+
const EdusAccountDialog = {
|
|
20889
|
+
open() {
|
|
20890
|
+
setAccountOpen(true);
|
|
20895
20891
|
},
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
color: "var(--dsw-alias-label-tertiary)",
|
|
20899
|
-
fontSize: 11,
|
|
20900
|
-
overflow: "hidden",
|
|
20901
|
-
textOverflow: "ellipsis",
|
|
20902
|
-
whiteSpace: "nowrap"
|
|
20892
|
+
close() {
|
|
20893
|
+
setAccountOpen(false);
|
|
20903
20894
|
},
|
|
20904
|
-
|
|
20905
|
-
|
|
20906
|
-
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
background: "#fff"
|
|
20895
|
+
subscribe(listener) {
|
|
20896
|
+
accountListeners.add(listener);
|
|
20897
|
+
return () => {
|
|
20898
|
+
accountListeners.delete(listener);
|
|
20899
|
+
};
|
|
20910
20900
|
},
|
|
20911
|
-
|
|
20901
|
+
getSnapshot: () => accountOpen
|
|
20902
|
+
};
|
|
20903
|
+
function useAccountOpen() {
|
|
20904
|
+
return (0, react.useSyncExternalStore)(EdusAccountDialog.subscribe, EdusAccountDialog.getSnapshot, () => false);
|
|
20905
|
+
}
|
|
20906
|
+
const ui = {
|
|
20907
|
+
backdrop: {
|
|
20912
20908
|
position: "fixed",
|
|
20913
20909
|
inset: 0,
|
|
20914
|
-
zIndex:
|
|
20910
|
+
zIndex: 1200,
|
|
20915
20911
|
display: "grid",
|
|
20916
20912
|
placeItems: "center",
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
backdropFilter: "blur(5px)"
|
|
20913
|
+
background: "rgb(0 0 0 / .35)",
|
|
20914
|
+
pointerEvents: "auto"
|
|
20920
20915
|
},
|
|
20921
|
-
|
|
20922
|
-
|
|
20923
|
-
|
|
20924
|
-
|
|
20925
|
-
borderRadius: 16,
|
|
20916
|
+
card: {
|
|
20917
|
+
position: "relative",
|
|
20918
|
+
boxSizing: "border-box",
|
|
20919
|
+
width: "min(380px, calc(100vw - 32px))",
|
|
20926
20920
|
background: "var(--dsw-alias-bg-base)",
|
|
20927
|
-
|
|
20928
|
-
|
|
20929
|
-
|
|
20930
|
-
|
|
20931
|
-
background: "linear-gradient(135deg, #173329 0%, #29553d 100%)",
|
|
20932
|
-
color: "#f7fbf8"
|
|
20921
|
+
color: "var(--dsw-alias-label-primary)",
|
|
20922
|
+
padding: "28px 28px 22px",
|
|
20923
|
+
borderRadius: 14,
|
|
20924
|
+
boxShadow: "0 20px 60px rgb(0 0 0 / 25%)"
|
|
20933
20925
|
},
|
|
20934
|
-
|
|
20935
|
-
|
|
20936
|
-
|
|
20937
|
-
|
|
20938
|
-
|
|
20939
|
-
|
|
20926
|
+
close: {
|
|
20927
|
+
position: "absolute",
|
|
20928
|
+
top: 12,
|
|
20929
|
+
right: 12,
|
|
20930
|
+
display: "grid",
|
|
20931
|
+
placeItems: "center",
|
|
20932
|
+
width: 28,
|
|
20933
|
+
height: 28,
|
|
20934
|
+
border: 0,
|
|
20935
|
+
borderRadius: 7,
|
|
20936
|
+
padding: 0,
|
|
20937
|
+
background: "transparent",
|
|
20938
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
20939
|
+
cursor: "pointer"
|
|
20940
20940
|
},
|
|
20941
20941
|
title: {
|
|
20942
|
-
margin:
|
|
20943
|
-
fontSize:
|
|
20944
|
-
|
|
20945
|
-
letterSpacing: "-.02em"
|
|
20942
|
+
margin: 0,
|
|
20943
|
+
fontSize: 18,
|
|
20944
|
+
fontWeight: 650
|
|
20946
20945
|
},
|
|
20947
|
-
|
|
20948
|
-
|
|
20949
|
-
margin: "0 0 16px",
|
|
20946
|
+
intro: {
|
|
20947
|
+
margin: "6px 0 8px",
|
|
20950
20948
|
color: "var(--dsw-alias-label-secondary)",
|
|
20951
20949
|
fontSize: 13,
|
|
20952
|
-
lineHeight: 1.
|
|
20950
|
+
lineHeight: 1.5
|
|
20953
20951
|
},
|
|
20954
|
-
|
|
20955
|
-
|
|
20952
|
+
dialogField: {
|
|
20953
|
+
height: 40,
|
|
20954
|
+
borderRadius: 9,
|
|
20955
|
+
padding: "0 12px"
|
|
20956
|
+
},
|
|
20957
|
+
dialogPrimary: {
|
|
20956
20958
|
width: "100%",
|
|
20957
|
-
|
|
20958
|
-
borderRadius:
|
|
20959
|
-
|
|
20960
|
-
color: "var(--dsw-alias-label-primary)",
|
|
20961
|
-
background: "var(--dsw-alias-bg-base)",
|
|
20962
|
-
font: "inherit",
|
|
20963
|
-
fontSize: 13
|
|
20959
|
+
height: 42,
|
|
20960
|
+
borderRadius: 9,
|
|
20961
|
+
fontSize: 14
|
|
20964
20962
|
},
|
|
20965
|
-
|
|
20963
|
+
dock: {
|
|
20964
|
+
boxSizing: "border-box",
|
|
20965
|
+
width: "calc(100% - 2 * var(--dsh-composer-side-clearance) - 4 * var(--dsh-composer-dock-inset))",
|
|
20966
|
+
margin: "0 auto"
|
|
20967
|
+
},
|
|
20968
|
+
banner: {
|
|
20969
|
+
boxSizing: "border-box",
|
|
20966
20970
|
display: "flex",
|
|
20967
|
-
alignItems: "
|
|
20971
|
+
alignItems: "center",
|
|
20968
20972
|
gap: 10,
|
|
20969
|
-
|
|
20970
|
-
|
|
20971
|
-
|
|
20972
|
-
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
|
|
20976
|
-
|
|
20977
|
-
},
|
|
20978
|
-
optionTitle: {
|
|
20979
|
-
display: "block",
|
|
20973
|
+
width: "100%",
|
|
20974
|
+
maxWidth: "calc(var(--dsh-composer-card-max-width) - 4 * var(--dsh-composer-dock-inset))",
|
|
20975
|
+
height: 36,
|
|
20976
|
+
margin: "0 auto",
|
|
20977
|
+
padding: "4px 5px 4px 12px",
|
|
20978
|
+
borderRadius: "var(--dsw-radius-md)",
|
|
20979
|
+
background: "var(--dsw-alias-bg-base)",
|
|
20980
|
+
boxShadow: "var(--dsw-elevation-panel)",
|
|
20980
20981
|
color: "var(--dsw-alias-label-primary)",
|
|
20981
|
-
fontSize: 13
|
|
20982
|
-
fontWeight: 650
|
|
20982
|
+
fontSize: 13
|
|
20983
20983
|
},
|
|
20984
|
-
|
|
20985
|
-
|
|
20986
|
-
|
|
20987
|
-
|
|
20988
|
-
|
|
20989
|
-
|
|
20984
|
+
bannerText: {
|
|
20985
|
+
flex: 1,
|
|
20986
|
+
minWidth: 0,
|
|
20987
|
+
overflow: "hidden",
|
|
20988
|
+
textOverflow: "ellipsis",
|
|
20989
|
+
whiteSpace: "nowrap"
|
|
20990
20990
|
},
|
|
20991
|
-
|
|
20992
|
-
|
|
20993
|
-
|
|
20991
|
+
primary: {
|
|
20992
|
+
flex: "none",
|
|
20993
|
+
height: 28,
|
|
20994
|
+
border: "none",
|
|
20995
|
+
borderRadius: "var(--dsw-radius-sm, 6px)",
|
|
20996
|
+
padding: "0 12px",
|
|
20997
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
20998
|
+
color: "var(--dsw-alias-label-primary-inverted)",
|
|
20999
|
+
font: "inherit",
|
|
20994
21000
|
fontSize: 12,
|
|
20995
|
-
|
|
20996
|
-
|
|
20997
|
-
|
|
21001
|
+
fontWeight: 650,
|
|
21002
|
+
cursor: "pointer"
|
|
21003
|
+
},
|
|
21004
|
+
footer: {
|
|
21005
|
+
boxSizing: "border-box",
|
|
20998
21006
|
display: "flex",
|
|
20999
|
-
|
|
21000
|
-
|
|
21001
|
-
|
|
21007
|
+
alignItems: "center",
|
|
21008
|
+
justifyContent: "center",
|
|
21009
|
+
gap: 6,
|
|
21010
|
+
width: "100%",
|
|
21011
|
+
padding: "8px 10px",
|
|
21012
|
+
border: "none",
|
|
21013
|
+
borderRadius: 8,
|
|
21014
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
21015
|
+
color: "var(--dsw-alias-label-primary-inverted)",
|
|
21016
|
+
font: "inherit",
|
|
21017
|
+
fontSize: 13,
|
|
21018
|
+
fontWeight: 650,
|
|
21019
|
+
cursor: "pointer"
|
|
21002
21020
|
},
|
|
21003
|
-
|
|
21021
|
+
account: {
|
|
21022
|
+
boxSizing: "border-box",
|
|
21004
21023
|
display: "flex",
|
|
21005
21024
|
alignItems: "center",
|
|
21006
21025
|
gap: 8,
|
|
21007
|
-
|
|
21008
|
-
|
|
21009
|
-
|
|
21010
|
-
|
|
21026
|
+
width: "100%",
|
|
21027
|
+
padding: "6px 8px",
|
|
21028
|
+
border: "none",
|
|
21029
|
+
borderRadius: 8,
|
|
21030
|
+
background: "var(--dsw-alias-bg-layer-1, rgb(0 0 0 / 4%))",
|
|
21031
|
+
color: "var(--dsw-alias-label-primary)",
|
|
21032
|
+
font: "inherit",
|
|
21033
|
+
fontSize: 13,
|
|
21034
|
+
textAlign: "left",
|
|
21035
|
+
cursor: "pointer",
|
|
21036
|
+
transition: "background 120ms"
|
|
21011
21037
|
},
|
|
21012
|
-
|
|
21013
|
-
|
|
21038
|
+
accountRail: {
|
|
21039
|
+
boxSizing: "border-box",
|
|
21040
|
+
display: "grid",
|
|
21041
|
+
placeItems: "center",
|
|
21042
|
+
width: 36,
|
|
21043
|
+
height: 36,
|
|
21044
|
+
marginBottom: 6,
|
|
21045
|
+
border: "none",
|
|
21046
|
+
borderRadius: 8,
|
|
21047
|
+
padding: 0,
|
|
21048
|
+
background: "var(--dsw-alias-bg-layer-1, rgb(0 0 0 / 4%))",
|
|
21049
|
+
cursor: "pointer",
|
|
21050
|
+
transition: "background 120ms"
|
|
21051
|
+
},
|
|
21052
|
+
accountHover: { background: "var(--dsw-alias-interactive-bg-hover, rgb(0 0 0 / 8%))" },
|
|
21053
|
+
chevron: {
|
|
21054
|
+
flex: "none",
|
|
21055
|
+
display: "grid",
|
|
21056
|
+
placeItems: "center",
|
|
21057
|
+
color: "var(--dsw-alias-label-tertiary)"
|
|
21058
|
+
},
|
|
21059
|
+
avatar: {
|
|
21060
|
+
flex: "none",
|
|
21061
|
+
display: "grid",
|
|
21062
|
+
placeItems: "center",
|
|
21063
|
+
width: 26,
|
|
21064
|
+
height: 26,
|
|
21065
|
+
borderRadius: "50%",
|
|
21066
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
21067
|
+
color: "var(--dsw-alias-label-primary-inverted)"
|
|
21068
|
+
},
|
|
21069
|
+
accountName: {
|
|
21014
21070
|
flex: 1,
|
|
21071
|
+
minWidth: 0,
|
|
21015
21072
|
overflow: "hidden",
|
|
21016
|
-
color: "var(--dsw-alias-brand-primary)",
|
|
21017
|
-
fontSize: 12,
|
|
21018
21073
|
textOverflow: "ellipsis",
|
|
21019
21074
|
whiteSpace: "nowrap"
|
|
21020
21075
|
},
|
|
21021
|
-
|
|
21076
|
+
badge: {
|
|
21077
|
+
flex: "none",
|
|
21078
|
+
padding: "1px 6px",
|
|
21079
|
+
borderRadius: 999,
|
|
21080
|
+
background: "var(--dsw-alias-bg-l2, rgb(0 0 0 / 6%))",
|
|
21081
|
+
color: "var(--dsw-alias-brand-primary)",
|
|
21082
|
+
fontSize: 11,
|
|
21083
|
+
fontWeight: 600
|
|
21084
|
+
},
|
|
21085
|
+
profile: {
|
|
21086
|
+
display: "flex",
|
|
21087
|
+
alignItems: "center",
|
|
21088
|
+
gap: 12,
|
|
21089
|
+
marginBottom: 18
|
|
21090
|
+
},
|
|
21091
|
+
profileAvatar: {
|
|
21092
|
+
flex: "none",
|
|
21022
21093
|
display: "grid",
|
|
21023
21094
|
placeItems: "center",
|
|
21024
|
-
width:
|
|
21025
|
-
height:
|
|
21095
|
+
width: 44,
|
|
21096
|
+
height: 44,
|
|
21026
21097
|
borderRadius: "50%",
|
|
21027
|
-
background: "
|
|
21028
|
-
color: "
|
|
21029
|
-
fontSize: 18,
|
|
21030
|
-
fontWeight: 700
|
|
21098
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
21099
|
+
color: "var(--dsw-alias-label-primary-inverted)"
|
|
21031
21100
|
},
|
|
21032
|
-
|
|
21101
|
+
profileName: {
|
|
21102
|
+
margin: 0,
|
|
21103
|
+
fontSize: 16,
|
|
21104
|
+
fontWeight: 650,
|
|
21105
|
+
overflow: "hidden",
|
|
21106
|
+
textOverflow: "ellipsis",
|
|
21107
|
+
whiteSpace: "nowrap"
|
|
21108
|
+
},
|
|
21109
|
+
profileSub: {
|
|
21110
|
+
margin: "2px 0 0",
|
|
21111
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
21112
|
+
fontSize: 12
|
|
21113
|
+
},
|
|
21114
|
+
section: {
|
|
21115
|
+
margin: "0 0 14px",
|
|
21116
|
+
padding: "12px 14px",
|
|
21117
|
+
borderRadius: 10,
|
|
21118
|
+
border: "1px solid var(--dsw-alias-border-l2)"
|
|
21119
|
+
},
|
|
21120
|
+
sectionTitle: {
|
|
21121
|
+
margin: "0 0 8px",
|
|
21122
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
21123
|
+
fontSize: 12,
|
|
21124
|
+
fontWeight: 600
|
|
21125
|
+
},
|
|
21126
|
+
row: {
|
|
21127
|
+
display: "flex",
|
|
21128
|
+
justifyContent: "space-between",
|
|
21129
|
+
gap: 12,
|
|
21130
|
+
padding: "3px 0",
|
|
21131
|
+
fontSize: 13
|
|
21132
|
+
},
|
|
21133
|
+
rowLabel: { color: "var(--dsw-alias-label-tertiary)" },
|
|
21134
|
+
meter: {
|
|
21135
|
+
height: 6,
|
|
21136
|
+
margin: "6px 0 4px",
|
|
21137
|
+
borderRadius: 999,
|
|
21138
|
+
background: "var(--dsw-alias-border-l2)",
|
|
21139
|
+
overflow: "hidden"
|
|
21140
|
+
},
|
|
21141
|
+
status: {
|
|
21142
|
+
margin: "0 0 12px",
|
|
21143
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
21144
|
+
fontSize: 12
|
|
21145
|
+
},
|
|
21146
|
+
errorText: {
|
|
21147
|
+
margin: "0 0 12px",
|
|
21148
|
+
color: "var(--dsw-alias-state-error-primary)",
|
|
21149
|
+
fontSize: 12
|
|
21150
|
+
},
|
|
21151
|
+
support: {
|
|
21033
21152
|
display: "flex",
|
|
21034
|
-
gap: 14,
|
|
21035
21153
|
alignItems: "center",
|
|
21036
|
-
|
|
21037
|
-
|
|
21038
|
-
|
|
21039
|
-
borderRadius:
|
|
21040
|
-
background: "var(--dsw-alias-bg-layer-1)"
|
|
21154
|
+
gap: 12,
|
|
21155
|
+
margin: "0",
|
|
21156
|
+
padding: "10px 12px",
|
|
21157
|
+
borderRadius: 10,
|
|
21158
|
+
background: "var(--dsw-alias-bg-layer-1, rgb(0 0 0 / 4%))"
|
|
21041
21159
|
},
|
|
21042
|
-
|
|
21160
|
+
supportQr: {
|
|
21043
21161
|
flex: "none",
|
|
21044
|
-
width:
|
|
21045
|
-
height:
|
|
21046
|
-
borderRadius:
|
|
21162
|
+
width: 84,
|
|
21163
|
+
height: 84,
|
|
21164
|
+
borderRadius: 6,
|
|
21047
21165
|
background: "#fff",
|
|
21048
21166
|
objectFit: "contain"
|
|
21049
21167
|
},
|
|
21050
|
-
|
|
21168
|
+
supportTitle: {
|
|
21051
21169
|
margin: 0,
|
|
21052
|
-
color: "var(--dsw-alias-label-primary)",
|
|
21053
21170
|
fontSize: 13,
|
|
21054
21171
|
fontWeight: 650
|
|
21055
21172
|
},
|
|
21056
|
-
|
|
21057
|
-
margin: "
|
|
21173
|
+
supportText: {
|
|
21174
|
+
margin: "4px 0 0",
|
|
21058
21175
|
color: "var(--dsw-alias-label-secondary)",
|
|
21059
21176
|
fontSize: 12,
|
|
21060
21177
|
lineHeight: 1.55
|
|
21061
21178
|
},
|
|
21062
|
-
|
|
21063
|
-
|
|
21064
|
-
|
|
21065
|
-
|
|
21066
|
-
|
|
21067
|
-
|
|
21068
|
-
|
|
21069
|
-
|
|
21070
|
-
|
|
21179
|
+
dialogActions: {
|
|
21180
|
+
display: "flex",
|
|
21181
|
+
justifyContent: "flex-end",
|
|
21182
|
+
gap: 8,
|
|
21183
|
+
marginTop: 4
|
|
21184
|
+
},
|
|
21185
|
+
quiet: {
|
|
21186
|
+
height: 32,
|
|
21187
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
21188
|
+
borderRadius: 8,
|
|
21189
|
+
padding: "0 14px",
|
|
21190
|
+
background: "transparent",
|
|
21191
|
+
color: "var(--dsw-alias-label-primary)",
|
|
21192
|
+
font: "inherit",
|
|
21193
|
+
fontSize: 13,
|
|
21194
|
+
cursor: "pointer"
|
|
21195
|
+
},
|
|
21196
|
+
danger: {
|
|
21197
|
+
height: 32,
|
|
21198
|
+
border: "none",
|
|
21199
|
+
borderRadius: 8,
|
|
21200
|
+
padding: "0 14px",
|
|
21201
|
+
background: "var(--dsw-alias-state-error-primary)",
|
|
21202
|
+
color: "#fff",
|
|
21203
|
+
font: "inherit",
|
|
21204
|
+
fontSize: 13,
|
|
21205
|
+
fontWeight: 600,
|
|
21206
|
+
cursor: "pointer"
|
|
21207
|
+
},
|
|
21208
|
+
footerRail: {
|
|
21209
|
+
boxSizing: "border-box",
|
|
21210
|
+
display: "grid",
|
|
21211
|
+
placeItems: "center",
|
|
21212
|
+
width: 36,
|
|
21213
|
+
height: 36,
|
|
21214
|
+
marginBottom: 6,
|
|
21215
|
+
border: "none",
|
|
21216
|
+
borderRadius: 8,
|
|
21217
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
21218
|
+
color: "var(--dsw-alias-label-primary-inverted)",
|
|
21219
|
+
cursor: "pointer"
|
|
21071
21220
|
}
|
|
21072
21221
|
};
|
|
21073
|
-
|
|
21074
|
-
|
|
21075
|
-
|
|
21076
|
-
|
|
21077
|
-
|
|
21078
|
-
|
|
21222
|
+
function UserIcon() {
|
|
21223
|
+
return (0, react_jsx_runtime.jsxs)("svg", {
|
|
21224
|
+
width: 16,
|
|
21225
|
+
height: 16,
|
|
21226
|
+
viewBox: "0 0 16 16",
|
|
21227
|
+
fill: "none",
|
|
21228
|
+
stroke: "currentColor",
|
|
21229
|
+
strokeWidth: 1.5,
|
|
21230
|
+
strokeLinecap: "round",
|
|
21231
|
+
"aria-hidden": true,
|
|
21232
|
+
children: [(0, react_jsx_runtime.jsx)("circle", {
|
|
21233
|
+
cx: "8",
|
|
21234
|
+
cy: "5.5",
|
|
21235
|
+
r: "2.75"
|
|
21236
|
+
}), (0, react_jsx_runtime.jsx)("path", { d: "M2.75 13.5c.6-2.4 2.7-3.9 5.25-3.9s4.65 1.5 5.25 3.9" })]
|
|
21079
21237
|
});
|
|
21080
|
-
|
|
21081
|
-
|
|
21082
|
-
|
|
21083
|
-
|
|
21084
|
-
|
|
21085
|
-
|
|
21086
|
-
|
|
21087
|
-
|
|
21088
|
-
|
|
21089
|
-
|
|
21090
|
-
|
|
21091
|
-
|
|
21092
|
-
|
|
21093
|
-
children: "该功能需要开通会员后使用。请用微信扫描左侧二维码添加客服咨询开通。"
|
|
21094
|
-
})]
|
|
21095
|
-
})]
|
|
21238
|
+
}
|
|
21239
|
+
function ChevronIcon() {
|
|
21240
|
+
return (0, react_jsx_runtime.jsx)("svg", {
|
|
21241
|
+
width: 14,
|
|
21242
|
+
height: 14,
|
|
21243
|
+
viewBox: "0 0 16 16",
|
|
21244
|
+
fill: "none",
|
|
21245
|
+
stroke: "currentColor",
|
|
21246
|
+
strokeWidth: 1.6,
|
|
21247
|
+
strokeLinecap: "round",
|
|
21248
|
+
strokeLinejoin: "round",
|
|
21249
|
+
"aria-hidden": true,
|
|
21250
|
+
children: (0, react_jsx_runtime.jsx)("path", { d: "M6 4l4 4-4 4" })
|
|
21096
21251
|
});
|
|
21097
21252
|
}
|
|
21098
|
-
|
|
21099
|
-
|
|
21253
|
+
function CloseIcon() {
|
|
21254
|
+
return (0, react_jsx_runtime.jsx)("svg", {
|
|
21255
|
+
width: 16,
|
|
21256
|
+
height: 16,
|
|
21257
|
+
viewBox: "0 0 16 16",
|
|
21258
|
+
fill: "none",
|
|
21259
|
+
stroke: "currentColor",
|
|
21260
|
+
strokeWidth: 1.6,
|
|
21261
|
+
strokeLinecap: "round",
|
|
21262
|
+
"aria-hidden": true,
|
|
21263
|
+
children: (0, react_jsx_runtime.jsx)("path", { d: "M4 4l8 8M12 4l-8 8" })
|
|
21264
|
+
});
|
|
21265
|
+
}
|
|
21266
|
+
/** 全局登录弹窗:已登录时不渲染。对话、我的作品等所有需要登录的入口都打开它。 */
|
|
21267
|
+
function LoginDialogOverlay({ remote }) {
|
|
21268
|
+
const open = useDialogOpen();
|
|
21100
21269
|
const account = useEdusLogin();
|
|
21101
|
-
const
|
|
21102
|
-
const [destination, setDestination] = (0, react.useState)("new");
|
|
21103
|
-
const [title, setTitle] = (0, react.useState)("");
|
|
21270
|
+
const visible = open && account === null;
|
|
21104
21271
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
21105
|
-
const
|
|
21106
|
-
|
|
21107
|
-
|
|
21108
|
-
|
|
21109
|
-
|
|
21110
|
-
|
|
21111
|
-
|
|
21112
|
-
|
|
21113
|
-
|
|
21114
|
-
|
|
21115
|
-
|
|
21116
|
-
|
|
21117
|
-
|
|
21118
|
-
|
|
21119
|
-
|
|
21120
|
-
|
|
21121
|
-
|
|
21122
|
-
|
|
21123
|
-
|
|
21124
|
-
|
|
21125
|
-
|
|
21126
|
-
|
|
21127
|
-
|
|
21128
|
-
|
|
21129
|
-
|
|
21130
|
-
|
|
21131
|
-
|
|
21132
|
-
|
|
21133
|
-
|
|
21134
|
-
|
|
21135
|
-
|
|
21136
|
-
|
|
21137
|
-
|
|
21138
|
-
|
|
21139
|
-
|
|
21140
|
-
|
|
21141
|
-
|
|
21142
|
-
|
|
21143
|
-
|
|
21144
|
-
|
|
21145
|
-
|
|
21146
|
-
|
|
21147
|
-
|
|
21148
|
-
|
|
21149
|
-
|
|
21150
|
-
|
|
21151
|
-
|
|
21152
|
-
|
|
21153
|
-
|
|
21154
|
-
|
|
21155
|
-
|
|
21156
|
-
|
|
21157
|
-
|
|
21158
|
-
|
|
21159
|
-
|
|
21160
|
-
|
|
21161
|
-
|
|
21162
|
-
|
|
21163
|
-
|
|
21164
|
-
|
|
21165
|
-
|
|
21166
|
-
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21172
|
-
|
|
21173
|
-
|
|
21174
|
-
|
|
21175
|
-
|
|
21176
|
-
|
|
21177
|
-
|
|
21178
|
-
|
|
21179
|
-
|
|
21180
|
-
|
|
21181
|
-
|
|
21182
|
-
|
|
21183
|
-
|
|
21184
|
-
|
|
21272
|
+
const close = (0, react.useCallback)(() => {
|
|
21273
|
+
if (!busy) EdusLoginDialog.close();
|
|
21274
|
+
}, [busy]);
|
|
21275
|
+
(0, react.useEffect)(() => {
|
|
21276
|
+
if (!visible) return;
|
|
21277
|
+
const onKey = (event) => {
|
|
21278
|
+
if (event.key === "Escape") close();
|
|
21279
|
+
};
|
|
21280
|
+
window.addEventListener("keydown", onKey);
|
|
21281
|
+
return () => {
|
|
21282
|
+
window.removeEventListener("keydown", onKey);
|
|
21283
|
+
};
|
|
21284
|
+
}, [visible, close]);
|
|
21285
|
+
if (!visible) return null;
|
|
21286
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
21287
|
+
role: "dialog",
|
|
21288
|
+
"aria-modal": "true",
|
|
21289
|
+
"aria-labelledby": "edus-login-dialog-title",
|
|
21290
|
+
style: ui.backdrop,
|
|
21291
|
+
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
21292
|
+
style: ui.card,
|
|
21293
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
21294
|
+
type: "button",
|
|
21295
|
+
"aria-label": "关闭",
|
|
21296
|
+
title: "关闭",
|
|
21297
|
+
style: ui.close,
|
|
21298
|
+
disabled: busy,
|
|
21299
|
+
onClick: close,
|
|
21300
|
+
children: (0, react_jsx_runtime.jsx)(CloseIcon, {})
|
|
21301
|
+
}), (0, react_jsx_runtime.jsx)(EdusLoginPanel, {
|
|
21302
|
+
remote,
|
|
21303
|
+
intro: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("h2", {
|
|
21304
|
+
id: "edus-login-dialog-title",
|
|
21305
|
+
style: ui.title,
|
|
21306
|
+
children: "登录课成账号"
|
|
21307
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
21308
|
+
style: ui.intro,
|
|
21309
|
+
children: "登录后即可开始 AI 对话,查看和发布你的作品。"
|
|
21310
|
+
})] }),
|
|
21311
|
+
notice: EdusLoginDialog.notice(),
|
|
21312
|
+
onBusyChange: setBusy,
|
|
21313
|
+
onSuccess: (result) => {
|
|
21314
|
+
EdusAuthStore.set(result);
|
|
21315
|
+
EdusLoginDialog.close();
|
|
21316
|
+
},
|
|
21317
|
+
theme: {
|
|
21318
|
+
field: ui.dialogField,
|
|
21319
|
+
primary: ui.dialogPrimary
|
|
21320
|
+
}
|
|
21321
|
+
})]
|
|
21322
|
+
})
|
|
21323
|
+
});
|
|
21324
|
+
}
|
|
21325
|
+
/** 输入框上方的未登录横幅。 */
|
|
21326
|
+
function LoginDockBanner() {
|
|
21327
|
+
if (useEdusLogin() !== null) return null;
|
|
21328
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
21329
|
+
style: ui.dock,
|
|
21330
|
+
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
21331
|
+
style: ui.banner,
|
|
21332
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
21333
|
+
style: ui.bannerText,
|
|
21334
|
+
children: "登录课成账号后即可开始对话"
|
|
21335
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
21336
|
+
type: "button",
|
|
21337
|
+
style: ui.primary,
|
|
21338
|
+
onClick: EdusLoginDialog.open,
|
|
21339
|
+
children: "登录"
|
|
21340
|
+
})]
|
|
21341
|
+
})
|
|
21342
|
+
});
|
|
21343
|
+
}
|
|
21344
|
+
/** 侧边栏底部的账号入口:未登录为登录按钮,已登录显示当前账号;收起为窄栏时只显示图标。 */
|
|
21345
|
+
function LoginFooterAction({ wide }) {
|
|
21346
|
+
const account = useEdusLogin();
|
|
21347
|
+
const [hover, setHover] = (0, react.useState)(false);
|
|
21348
|
+
if (account === null) return wide ? (0, react_jsx_runtime.jsxs)("button", {
|
|
21349
|
+
type: "button",
|
|
21350
|
+
style: ui.footer,
|
|
21351
|
+
onClick: EdusLoginDialog.open,
|
|
21352
|
+
children: [(0, react_jsx_runtime.jsx)(UserIcon, {}), "登录课成账号"]
|
|
21353
|
+
}) : (0, react_jsx_runtime.jsx)("button", {
|
|
21354
|
+
type: "button",
|
|
21355
|
+
title: "登录课成账号",
|
|
21356
|
+
"aria-label": "登录课成账号",
|
|
21357
|
+
style: ui.footerRail,
|
|
21358
|
+
onClick: EdusLoginDialog.open,
|
|
21359
|
+
children: (0, react_jsx_runtime.jsx)(UserIcon, {})
|
|
21360
|
+
});
|
|
21361
|
+
const name = displayName(account);
|
|
21362
|
+
const hoverProps = {
|
|
21363
|
+
onMouseEnter: () => setHover(true),
|
|
21364
|
+
onMouseLeave: () => setHover(false)
|
|
21185
21365
|
};
|
|
21186
|
-
|
|
21187
|
-
|
|
21188
|
-
|
|
21189
|
-
|
|
21366
|
+
return wide ? (0, react_jsx_runtime.jsxs)("button", {
|
|
21367
|
+
type: "button",
|
|
21368
|
+
title: "账号信息",
|
|
21369
|
+
style: {
|
|
21370
|
+
...ui.account,
|
|
21371
|
+
...hover ? ui.accountHover : null
|
|
21372
|
+
},
|
|
21373
|
+
onClick: EdusAccountDialog.open,
|
|
21374
|
+
...hoverProps,
|
|
21190
21375
|
children: [
|
|
21191
|
-
(0, react_jsx_runtime.
|
|
21192
|
-
style:
|
|
21193
|
-
children:
|
|
21194
|
-
style: styles$1.primary,
|
|
21195
|
-
onClick: () => void open(),
|
|
21196
|
-
children: "发布网页"
|
|
21197
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
21198
|
-
style: styles$1.account,
|
|
21199
|
-
children: account === null ? "尚未登录" : `${account.title || "当前账号"} · ${account.phone}`
|
|
21200
|
-
})]
|
|
21376
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
21377
|
+
style: ui.avatar,
|
|
21378
|
+
children: (0, react_jsx_runtime.jsx)(UserIcon, {})
|
|
21201
21379
|
}),
|
|
21202
|
-
(0, react_jsx_runtime.jsx)("
|
|
21203
|
-
|
|
21204
|
-
|
|
21205
|
-
srcDoc: source,
|
|
21206
|
-
style: styles$1.frame
|
|
21380
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
21381
|
+
style: ui.accountName,
|
|
21382
|
+
children: name
|
|
21207
21383
|
}),
|
|
21208
|
-
|
|
21209
|
-
style:
|
|
21210
|
-
|
|
21211
|
-
|
|
21212
|
-
|
|
21213
|
-
|
|
21214
|
-
|
|
21215
|
-
|
|
21216
|
-
|
|
21217
|
-
|
|
21218
|
-
|
|
21219
|
-
|
|
21220
|
-
|
|
21221
|
-
|
|
21222
|
-
|
|
21223
|
-
|
|
21224
|
-
|
|
21225
|
-
|
|
21226
|
-
|
|
21227
|
-
|
|
21228
|
-
|
|
21229
|
-
|
|
21230
|
-
|
|
21231
|
-
|
|
21232
|
-
|
|
21233
|
-
|
|
21234
|
-
|
|
21235
|
-
|
|
21236
|
-
|
|
21237
|
-
|
|
21238
|
-
|
|
21239
|
-
|
|
21240
|
-
|
|
21241
|
-
|
|
21242
|
-
|
|
21243
|
-
|
|
21244
|
-
|
|
21245
|
-
|
|
21246
|
-
|
|
21247
|
-
|
|
21248
|
-
|
|
21249
|
-
|
|
21250
|
-
|
|
21251
|
-
|
|
21252
|
-
|
|
21253
|
-
|
|
21254
|
-
|
|
21255
|
-
|
|
21256
|
-
|
|
21257
|
-
|
|
21258
|
-
|
|
21259
|
-
|
|
21260
|
-
|
|
21261
|
-
|
|
21262
|
-
|
|
21263
|
-
|
|
21264
|
-
|
|
21265
|
-
|
|
21266
|
-
|
|
21267
|
-
|
|
21268
|
-
|
|
21269
|
-
|
|
21270
|
-
|
|
21271
|
-
|
|
21272
|
-
|
|
21273
|
-
|
|
21274
|
-
|
|
21275
|
-
|
|
21276
|
-
|
|
21277
|
-
|
|
21278
|
-
|
|
21279
|
-
|
|
21280
|
-
|
|
21281
|
-
|
|
21282
|
-
|
|
21283
|
-
|
|
21284
|
-
|
|
21285
|
-
|
|
21286
|
-
|
|
21287
|
-
|
|
21288
|
-
|
|
21289
|
-
|
|
21290
|
-
|
|
21291
|
-
|
|
21292
|
-
|
|
21293
|
-
|
|
21294
|
-
|
|
21295
|
-
|
|
21296
|
-
|
|
21297
|
-
|
|
21298
|
-
|
|
21299
|
-
|
|
21300
|
-
|
|
21301
|
-
|
|
21302
|
-
|
|
21303
|
-
|
|
21304
|
-
|
|
21305
|
-
|
|
21306
|
-
|
|
21307
|
-
|
|
21308
|
-
|
|
21309
|
-
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21313
|
-
|
|
21314
|
-
|
|
21315
|
-
|
|
21316
|
-
|
|
21317
|
-
|
|
21318
|
-
|
|
21319
|
-
|
|
21320
|
-
|
|
21321
|
-
|
|
21322
|
-
|
|
21323
|
-
|
|
21324
|
-
|
|
21325
|
-
|
|
21326
|
-
|
|
21327
|
-
|
|
21328
|
-
|
|
21329
|
-
|
|
21330
|
-
|
|
21331
|
-
|
|
21332
|
-
|
|
21333
|
-
|
|
21334
|
-
|
|
21335
|
-
|
|
21336
|
-
|
|
21337
|
-
|
|
21338
|
-
|
|
21339
|
-
|
|
21340
|
-
|
|
21341
|
-
|
|
21342
|
-
|
|
21343
|
-
|
|
21344
|
-
|
|
21345
|
-
|
|
21346
|
-
|
|
21347
|
-
|
|
21348
|
-
|
|
21349
|
-
|
|
21350
|
-
|
|
21351
|
-
|
|
21352
|
-
|
|
21353
|
-
|
|
21354
|
-
|
|
21355
|
-
|
|
21356
|
-
|
|
21357
|
-
|
|
21358
|
-
|
|
21359
|
-
|
|
21360
|
-
|
|
21361
|
-
|
|
21362
|
-
|
|
21363
|
-
|
|
21364
|
-
|
|
21365
|
-
|
|
21366
|
-
|
|
21367
|
-
|
|
21368
|
-
|
|
21369
|
-
|
|
21370
|
-
|
|
21371
|
-
|
|
21372
|
-
|
|
21373
|
-
|
|
21374
|
-
|
|
21375
|
-
|
|
21376
|
-
|
|
21377
|
-
|
|
21378
|
-
|
|
21379
|
-
|
|
21380
|
-
|
|
21381
|
-
|
|
21382
|
-
|
|
21383
|
-
|
|
21384
|
-
|
|
21385
|
-
|
|
21386
|
-
|
|
21387
|
-
|
|
21388
|
-
|
|
21389
|
-
|
|
21390
|
-
|
|
21391
|
-
|
|
21392
|
-
|
|
21384
|
+
account.isVip && account.vipLevelName && (0, react_jsx_runtime.jsx)("span", {
|
|
21385
|
+
style: ui.badge,
|
|
21386
|
+
children: account.vipLevelName
|
|
21387
|
+
}),
|
|
21388
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
21389
|
+
style: ui.chevron,
|
|
21390
|
+
children: (0, react_jsx_runtime.jsx)(ChevronIcon, {})
|
|
21391
|
+
})
|
|
21392
|
+
]
|
|
21393
|
+
}) : (0, react_jsx_runtime.jsx)("button", {
|
|
21394
|
+
type: "button",
|
|
21395
|
+
title: `${name} · 账号信息`,
|
|
21396
|
+
"aria-label": "账号信息",
|
|
21397
|
+
style: {
|
|
21398
|
+
...ui.accountRail,
|
|
21399
|
+
...hover ? ui.accountHover : null
|
|
21400
|
+
},
|
|
21401
|
+
onClick: EdusAccountDialog.open,
|
|
21402
|
+
...hoverProps,
|
|
21403
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
21404
|
+
style: ui.avatar,
|
|
21405
|
+
children: (0, react_jsx_runtime.jsx)(UserIcon, {})
|
|
21406
|
+
})
|
|
21407
|
+
});
|
|
21408
|
+
}
|
|
21409
|
+
/** 客服(技术支持)微信二维码:开通会员或遇到问题时扫码添加。 */
|
|
21410
|
+
const SUPPORT_QR = "https://cdn.juzhenai.cn/assets/jishu-weixin-qrcode.jpg";
|
|
21411
|
+
function maskPhone(phone) {
|
|
21412
|
+
return /^\d{11}$/.test(phone) ? `${phone.slice(0, 3)}****${phone.slice(7)}` : phone;
|
|
21413
|
+
}
|
|
21414
|
+
function displayName(account) {
|
|
21415
|
+
return account.title || maskPhone(account.phone);
|
|
21416
|
+
}
|
|
21417
|
+
function formatTime(value) {
|
|
21418
|
+
if (!value) return "—";
|
|
21419
|
+
const date = new Date(value);
|
|
21420
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
21421
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
21422
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
21423
|
+
}
|
|
21424
|
+
/** 取整 */
|
|
21425
|
+
function formatPoints(value) {
|
|
21426
|
+
const amount = Number(value);
|
|
21427
|
+
return value === void 0 || value === "" || Number.isNaN(amount) ? "—" : Math.round(amount).toLocaleString("zh-CN");
|
|
21428
|
+
}
|
|
21429
|
+
function Row({ label, value }) {
|
|
21430
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
21431
|
+
style: ui.row,
|
|
21432
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
21433
|
+
style: ui.rowLabel,
|
|
21434
|
+
children: label
|
|
21435
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: value })]
|
|
21436
|
+
});
|
|
21437
|
+
}
|
|
21438
|
+
/** 账号信息弹窗:打开时用 token 拉一次最新信息,展示会员与模型用量,并提供退出登录。 */
|
|
21439
|
+
function AccountDialogOverlay({ remote }) {
|
|
21440
|
+
const open = useAccountOpen();
|
|
21441
|
+
const account = useEdusLogin();
|
|
21442
|
+
const visible = open && account !== null;
|
|
21443
|
+
const [refreshing, setRefreshing] = (0, react.useState)(false);
|
|
21444
|
+
const [error, setError] = (0, react.useState)("");
|
|
21445
|
+
const [confirmLogout, setConfirmLogout] = (0, react.useState)(false);
|
|
21446
|
+
const close = (0, react.useCallback)(() => {
|
|
21447
|
+
EdusAccountDialog.close();
|
|
21448
|
+
}, []);
|
|
21449
|
+
(0, react.useEffect)(() => {
|
|
21450
|
+
if (open && account === null) EdusAccountDialog.close();
|
|
21451
|
+
}, [open, account]);
|
|
21452
|
+
const token = account?.token;
|
|
21453
|
+
(0, react.useEffect)(() => {
|
|
21454
|
+
if (!open || token === void 0) return;
|
|
21455
|
+
let cancelled = false;
|
|
21456
|
+
setError("");
|
|
21457
|
+
setConfirmLogout(false);
|
|
21458
|
+
setRefreshing(true);
|
|
21459
|
+
remote.loginInfo(token).then((refreshed) => {
|
|
21460
|
+
if (!cancelled) EdusAuthStore.set(refreshed);
|
|
21461
|
+
}, (failure) => {
|
|
21462
|
+
if (!cancelled) setError(`刷新账号信息失败:${failure instanceof Error ? failure.message : String(failure)}`);
|
|
21463
|
+
}).finally(() => {
|
|
21464
|
+
if (!cancelled) setRefreshing(false);
|
|
21465
|
+
});
|
|
21466
|
+
return () => {
|
|
21467
|
+
cancelled = true;
|
|
21468
|
+
};
|
|
21469
|
+
}, [
|
|
21470
|
+
open,
|
|
21471
|
+
token,
|
|
21472
|
+
remote
|
|
21473
|
+
]);
|
|
21474
|
+
(0, react.useEffect)(() => {
|
|
21475
|
+
if (!visible) return;
|
|
21476
|
+
const onKey = (event) => {
|
|
21477
|
+
if (event.key === "Escape") close();
|
|
21478
|
+
};
|
|
21479
|
+
window.addEventListener("keydown", onKey);
|
|
21480
|
+
return () => {
|
|
21481
|
+
window.removeEventListener("keydown", onKey);
|
|
21482
|
+
};
|
|
21483
|
+
}, [visible, close]);
|
|
21484
|
+
if (!visible) return null;
|
|
21485
|
+
const limit = account.vipMonthLimit ?? 0;
|
|
21486
|
+
const monthCost = Number(account.llmMonthCost);
|
|
21487
|
+
const ratio = limit > 0 && !Number.isNaN(monthCost) ? Math.min(1, monthCost / limit) : 0;
|
|
21488
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
21489
|
+
role: "dialog",
|
|
21490
|
+
"aria-modal": "true",
|
|
21491
|
+
"aria-labelledby": "edus-account-dialog-title",
|
|
21492
|
+
style: ui.backdrop,
|
|
21493
|
+
onMouseDown: (event) => {
|
|
21494
|
+
if (event.target === event.currentTarget) close();
|
|
21495
|
+
},
|
|
21496
|
+
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
21497
|
+
style: ui.card,
|
|
21498
|
+
children: [
|
|
21499
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
21500
|
+
type: "button",
|
|
21501
|
+
"aria-label": "关闭",
|
|
21502
|
+
title: "关闭",
|
|
21503
|
+
style: ui.close,
|
|
21504
|
+
onClick: close,
|
|
21505
|
+
children: (0, react_jsx_runtime.jsx)(CloseIcon, {})
|
|
21506
|
+
}),
|
|
21507
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
21508
|
+
style: ui.profile,
|
|
21509
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
21510
|
+
style: ui.profileAvatar,
|
|
21511
|
+
children: (0, react_jsx_runtime.jsx)(UserIcon, {})
|
|
21512
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
21513
|
+
style: { minWidth: 0 },
|
|
21514
|
+
children: [(0, react_jsx_runtime.jsx)("h2", {
|
|
21515
|
+
id: "edus-account-dialog-title",
|
|
21516
|
+
style: ui.profileName,
|
|
21517
|
+
children: displayName(account)
|
|
21518
|
+
}), (0, react_jsx_runtime.jsxs)("p", {
|
|
21519
|
+
style: ui.profileSub,
|
|
21520
|
+
children: [maskPhone(account.phone), account.isAdmin ? " · 管理员" : ""]
|
|
21521
|
+
})]
|
|
21522
|
+
})]
|
|
21523
|
+
}),
|
|
21524
|
+
refreshing && (0, react_jsx_runtime.jsx)("p", {
|
|
21525
|
+
style: ui.status,
|
|
21526
|
+
role: "status",
|
|
21527
|
+
children: "正在刷新账号信息…"
|
|
21528
|
+
}),
|
|
21529
|
+
error !== "" && (0, react_jsx_runtime.jsx)("p", {
|
|
21530
|
+
style: ui.errorText,
|
|
21531
|
+
children: error
|
|
21532
|
+
}),
|
|
21533
|
+
(0, react_jsx_runtime.jsxs)("section", {
|
|
21534
|
+
style: ui.section,
|
|
21535
|
+
children: [
|
|
21536
|
+
(0, react_jsx_runtime.jsx)("h3", {
|
|
21537
|
+
style: ui.sectionTitle,
|
|
21538
|
+
children: "会员"
|
|
21539
|
+
}),
|
|
21540
|
+
(0, react_jsx_runtime.jsx)(Row, {
|
|
21541
|
+
label: "当前版本",
|
|
21542
|
+
value: account.isVip ? account.vipLevelName || `VIP ${account.vipLevel}` : "未开通"
|
|
21543
|
+
}),
|
|
21544
|
+
account.isVip && (0, react_jsx_runtime.jsx)(Row, {
|
|
21545
|
+
label: "到期时间",
|
|
21546
|
+
value: formatTime(account.vipEndTime)
|
|
21547
|
+
}),
|
|
21548
|
+
account.llmStatus !== void 0 && account.llmStatus !== null && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(Row, {
|
|
21549
|
+
label: "本月已用",
|
|
21550
|
+
value: limit > 0 ? `${formatPoints(account.llmMonthCost)} / ${formatPoints(limit)} 积分` : `${formatPoints(account.llmMonthCost)} 积分`
|
|
21551
|
+
}), limit > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
21552
|
+
style: ui.meter,
|
|
21553
|
+
"aria-hidden": true,
|
|
21554
|
+
children: (0, react_jsx_runtime.jsx)("div", { style: {
|
|
21555
|
+
width: `${ratio * 100}%`,
|
|
21556
|
+
height: "100%",
|
|
21557
|
+
background: ratio >= .9 ? "var(--dsw-alias-state-error-primary)" : "var(--dsw-alias-brand-primary)"
|
|
21558
|
+
} })
|
|
21559
|
+
})] }),
|
|
21560
|
+
account.isVip && limit === 0 && (0, react_jsx_runtime.jsx)(Row, {
|
|
21561
|
+
label: "每月额度",
|
|
21562
|
+
value: "不限"
|
|
21563
|
+
})
|
|
21564
|
+
]
|
|
21565
|
+
}),
|
|
21566
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
21567
|
+
style: ui.support,
|
|
21568
|
+
children: [(0, react_jsx_runtime.jsx)("img", {
|
|
21569
|
+
alt: "客服微信二维码",
|
|
21570
|
+
src: SUPPORT_QR,
|
|
21571
|
+
style: ui.supportQr
|
|
21572
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
21573
|
+
style: { minWidth: 0 },
|
|
21574
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
21575
|
+
style: ui.supportTitle,
|
|
21576
|
+
children: "联系客服"
|
|
21577
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
21578
|
+
style: ui.supportText,
|
|
21579
|
+
children: "需要开通会员或遇到问题,请用微信扫码添加客服。"
|
|
21580
|
+
})]
|
|
21393
21581
|
})]
|
|
21582
|
+
}),
|
|
21583
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
21584
|
+
style: ui.dialogActions,
|
|
21585
|
+
children: confirmLogout ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
21586
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
21587
|
+
style: {
|
|
21588
|
+
alignSelf: "center",
|
|
21589
|
+
marginRight: "auto",
|
|
21590
|
+
fontSize: 13
|
|
21591
|
+
},
|
|
21592
|
+
children: "确定退出登录?"
|
|
21593
|
+
}),
|
|
21594
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
21595
|
+
type: "button",
|
|
21596
|
+
style: ui.quiet,
|
|
21597
|
+
onClick: () => setConfirmLogout(false),
|
|
21598
|
+
children: "取消"
|
|
21599
|
+
}),
|
|
21600
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
21601
|
+
type: "button",
|
|
21602
|
+
style: ui.danger,
|
|
21603
|
+
onClick: () => {
|
|
21604
|
+
EdusAuthStore.logout();
|
|
21605
|
+
close();
|
|
21606
|
+
},
|
|
21607
|
+
children: "退出"
|
|
21608
|
+
})
|
|
21609
|
+
] }) : (0, react_jsx_runtime.jsx)("button", {
|
|
21610
|
+
type: "button",
|
|
21611
|
+
style: ui.quiet,
|
|
21612
|
+
onClick: () => setConfirmLogout(true),
|
|
21613
|
+
children: "退出登录"
|
|
21614
|
+
})
|
|
21394
21615
|
})
|
|
21395
|
-
|
|
21396
|
-
|
|
21616
|
+
]
|
|
21617
|
+
})
|
|
21397
21618
|
});
|
|
21398
21619
|
}
|
|
21399
21620
|
//#endregion
|
|
21400
|
-
//#region lib/types/client/
|
|
21401
|
-
|
|
21402
|
-
|
|
21403
|
-
|
|
21404
|
-
|
|
21405
|
-
|
|
21406
|
-
|
|
21407
|
-
|
|
21408
|
-
|
|
21409
|
-
* 三处共用一个弹窗开关,登录成功后弹窗关闭、横幅消失;侧边栏按钮转为显示当前
|
|
21410
|
-
* 账号,点击打开账号信息弹窗(AccountDialogOverlay)。
|
|
21411
|
-
*/
|
|
21412
|
-
let dialogOpen = false;
|
|
21413
|
-
const dialogListeners = /* @__PURE__ */ new Set();
|
|
21414
|
-
function setDialogOpen(next) {
|
|
21415
|
-
if (dialogOpen === next) return;
|
|
21416
|
-
dialogOpen = next;
|
|
21417
|
-
for (const listener of dialogListeners) listener();
|
|
21418
|
-
}
|
|
21419
|
-
const EdusLoginDialog = {
|
|
21420
|
-
open() {
|
|
21421
|
-
setDialogOpen(true);
|
|
21422
|
-
},
|
|
21423
|
-
close() {
|
|
21424
|
-
setDialogOpen(false);
|
|
21425
|
-
},
|
|
21426
|
-
subscribe(listener) {
|
|
21427
|
-
dialogListeners.add(listener);
|
|
21428
|
-
return () => {
|
|
21429
|
-
dialogListeners.delete(listener);
|
|
21621
|
+
//#region lib/types/client/HtmlPublishPreview.js
|
|
21622
|
+
function fileRef(address) {
|
|
21623
|
+
if (!address.startsWith("dsh-resource://file/session/")) return null;
|
|
21624
|
+
try {
|
|
21625
|
+
const [sessionId, ...path] = address.slice(28).split(/[?#]/, 1)[0]?.split("/") ?? [];
|
|
21626
|
+
if (sessionId === void 0 || sessionId === "" || path.length === 0) return null;
|
|
21627
|
+
return {
|
|
21628
|
+
sessionId: decodeURIComponent(sessionId),
|
|
21629
|
+
path: path.map(decodeURIComponent).join("/")
|
|
21430
21630
|
};
|
|
21431
|
-
}
|
|
21432
|
-
|
|
21433
|
-
|
|
21434
|
-
function useDialogOpen() {
|
|
21435
|
-
return (0, react.useSyncExternalStore)(EdusLoginDialog.subscribe, EdusLoginDialog.getSnapshot, () => false);
|
|
21436
|
-
}
|
|
21437
|
-
/** 账号信息弹窗的开关,与登录弹窗相互独立。 */
|
|
21438
|
-
let accountOpen = false;
|
|
21439
|
-
const accountListeners = /* @__PURE__ */ new Set();
|
|
21440
|
-
function setAccountOpen(next) {
|
|
21441
|
-
if (accountOpen === next) return;
|
|
21442
|
-
accountOpen = next;
|
|
21443
|
-
for (const listener of accountListeners) listener();
|
|
21631
|
+
} catch {
|
|
21632
|
+
return null;
|
|
21633
|
+
}
|
|
21444
21634
|
}
|
|
21445
|
-
|
|
21446
|
-
|
|
21447
|
-
setAccountOpen(true);
|
|
21448
|
-
},
|
|
21449
|
-
close() {
|
|
21450
|
-
setAccountOpen(false);
|
|
21451
|
-
},
|
|
21452
|
-
subscribe(listener) {
|
|
21453
|
-
accountListeners.add(listener);
|
|
21454
|
-
return () => {
|
|
21455
|
-
accountListeners.delete(listener);
|
|
21456
|
-
};
|
|
21457
|
-
},
|
|
21458
|
-
getSnapshot: () => accountOpen
|
|
21459
|
-
};
|
|
21460
|
-
function useAccountOpen() {
|
|
21461
|
-
return (0, react.useSyncExternalStore)(EdusAccountDialog.subscribe, EdusAccountDialog.getSnapshot, () => false);
|
|
21635
|
+
function basename(path) {
|
|
21636
|
+
return path.split("/").at(-1) ?? path;
|
|
21462
21637
|
}
|
|
21463
|
-
|
|
21464
|
-
|
|
21465
|
-
|
|
21466
|
-
|
|
21467
|
-
|
|
21468
|
-
display: "
|
|
21469
|
-
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
|
|
21473
|
-
card: {
|
|
21474
|
-
position: "relative",
|
|
21475
|
-
boxSizing: "border-box",
|
|
21476
|
-
width: "min(380px, calc(100vw - 32px))",
|
|
21477
|
-
background: "var(--dsw-alias-bg-base)",
|
|
21478
|
-
color: "var(--dsw-alias-label-primary)",
|
|
21479
|
-
padding: "28px 28px 22px",
|
|
21480
|
-
borderRadius: 14,
|
|
21481
|
-
boxShadow: "0 20px 60px rgb(0 0 0 / 25%)"
|
|
21482
|
-
},
|
|
21483
|
-
close: {
|
|
21484
|
-
position: "absolute",
|
|
21485
|
-
top: 12,
|
|
21486
|
-
right: 12,
|
|
21487
|
-
display: "grid",
|
|
21488
|
-
placeItems: "center",
|
|
21489
|
-
width: 28,
|
|
21490
|
-
height: 28,
|
|
21491
|
-
border: 0,
|
|
21492
|
-
borderRadius: 7,
|
|
21493
|
-
padding: 0,
|
|
21494
|
-
background: "transparent",
|
|
21495
|
-
color: "var(--dsw-alias-label-tertiary)",
|
|
21496
|
-
cursor: "pointer"
|
|
21497
|
-
},
|
|
21498
|
-
title: {
|
|
21499
|
-
margin: 0,
|
|
21500
|
-
fontSize: 18,
|
|
21501
|
-
fontWeight: 650
|
|
21502
|
-
},
|
|
21503
|
-
intro: {
|
|
21504
|
-
margin: "6px 0 8px",
|
|
21505
|
-
color: "var(--dsw-alias-label-secondary)",
|
|
21506
|
-
fontSize: 13,
|
|
21507
|
-
lineHeight: 1.5
|
|
21508
|
-
},
|
|
21509
|
-
dialogField: {
|
|
21510
|
-
height: 40,
|
|
21511
|
-
borderRadius: 9,
|
|
21512
|
-
padding: "0 12px"
|
|
21513
|
-
},
|
|
21514
|
-
dialogPrimary: {
|
|
21515
|
-
width: "100%",
|
|
21516
|
-
height: 42,
|
|
21517
|
-
borderRadius: 9,
|
|
21518
|
-
fontSize: 14
|
|
21519
|
-
},
|
|
21520
|
-
dock: {
|
|
21521
|
-
boxSizing: "border-box",
|
|
21522
|
-
width: "calc(100% - 2 * var(--dsh-composer-side-clearance) - 4 * var(--dsh-composer-dock-inset))",
|
|
21523
|
-
margin: "0 auto"
|
|
21638
|
+
/** 后端在未开通会员时返回的提示里带有这个字眼,此时改为引导扫码联系客服。 */
|
|
21639
|
+
const MEMBERSHIP_HINT = "需要开通会员";
|
|
21640
|
+
const SERVICE_QR = "https://cdn.juzhenai.cn/ai-edu/assets/wechat.webp";
|
|
21641
|
+
const styles$1 = {
|
|
21642
|
+
root: {
|
|
21643
|
+
display: "flex",
|
|
21644
|
+
flexDirection: "column",
|
|
21645
|
+
height: "100%",
|
|
21646
|
+
minHeight: 0,
|
|
21647
|
+
background: "var(--dsw-alias-bg-base)"
|
|
21524
21648
|
},
|
|
21525
|
-
|
|
21526
|
-
boxSizing: "border-box",
|
|
21649
|
+
bar: {
|
|
21527
21650
|
display: "flex",
|
|
21528
21651
|
alignItems: "center",
|
|
21529
|
-
gap:
|
|
21530
|
-
|
|
21531
|
-
|
|
21532
|
-
|
|
21533
|
-
|
|
21534
|
-
|
|
21535
|
-
|
|
21536
|
-
|
|
21537
|
-
|
|
21538
|
-
|
|
21539
|
-
|
|
21540
|
-
},
|
|
21541
|
-
bannerText: {
|
|
21542
|
-
flex: 1,
|
|
21543
|
-
minWidth: 0,
|
|
21544
|
-
overflow: "hidden",
|
|
21545
|
-
textOverflow: "ellipsis",
|
|
21546
|
-
whiteSpace: "nowrap"
|
|
21547
|
-
},
|
|
21548
|
-
primary: {
|
|
21549
|
-
flex: "none",
|
|
21550
|
-
height: 28,
|
|
21551
|
-
border: "none",
|
|
21552
|
-
borderRadius: "var(--dsw-radius-sm, 6px)",
|
|
21553
|
-
padding: "0 12px",
|
|
21554
|
-
background: "var(--dsw-alias-button-primary-fill)",
|
|
21555
|
-
color: "var(--dsw-alias-label-primary-inverted)",
|
|
21652
|
+
gap: 7,
|
|
21653
|
+
padding: "7px 10px",
|
|
21654
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
21655
|
+
background: "var(--dsw-alias-bg-layer-1)"
|
|
21656
|
+
},
|
|
21657
|
+
button: {
|
|
21658
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
21659
|
+
borderRadius: 6,
|
|
21660
|
+
padding: "4px 8px",
|
|
21661
|
+
background: "transparent",
|
|
21662
|
+
color: "var(--dsw-alias-label-primary)",
|
|
21556
21663
|
font: "inherit",
|
|
21557
21664
|
fontSize: 12,
|
|
21558
|
-
fontWeight: 650,
|
|
21559
21665
|
cursor: "pointer"
|
|
21560
21666
|
},
|
|
21561
|
-
|
|
21562
|
-
boxSizing: "border-box",
|
|
21563
|
-
display: "flex",
|
|
21564
|
-
alignItems: "center",
|
|
21565
|
-
justifyContent: "center",
|
|
21566
|
-
gap: 6,
|
|
21567
|
-
width: "100%",
|
|
21568
|
-
margin: "0 8px 6px",
|
|
21569
|
-
padding: "8px 10px",
|
|
21667
|
+
primary: {
|
|
21570
21668
|
border: "none",
|
|
21571
|
-
borderRadius:
|
|
21669
|
+
borderRadius: 7,
|
|
21670
|
+
padding: "6px 11px",
|
|
21572
21671
|
background: "var(--dsw-alias-button-primary-fill)",
|
|
21573
21672
|
color: "var(--dsw-alias-label-primary-inverted)",
|
|
21574
21673
|
font: "inherit",
|
|
21575
|
-
fontSize:
|
|
21674
|
+
fontSize: 12,
|
|
21576
21675
|
fontWeight: 650,
|
|
21577
21676
|
cursor: "pointer"
|
|
21578
21677
|
},
|
|
21579
21678
|
account: {
|
|
21580
|
-
|
|
21581
|
-
|
|
21582
|
-
|
|
21583
|
-
|
|
21584
|
-
|
|
21585
|
-
|
|
21586
|
-
padding: "6px 8px",
|
|
21587
|
-
border: "none",
|
|
21588
|
-
borderRadius: 8,
|
|
21589
|
-
background: "transparent",
|
|
21590
|
-
color: "var(--dsw-alias-label-primary)",
|
|
21591
|
-
font: "inherit",
|
|
21592
|
-
fontSize: 13,
|
|
21593
|
-
textAlign: "left",
|
|
21594
|
-
cursor: "pointer"
|
|
21679
|
+
marginLeft: "auto",
|
|
21680
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
21681
|
+
fontSize: 11,
|
|
21682
|
+
overflow: "hidden",
|
|
21683
|
+
textOverflow: "ellipsis",
|
|
21684
|
+
whiteSpace: "nowrap"
|
|
21595
21685
|
},
|
|
21596
|
-
|
|
21597
|
-
|
|
21598
|
-
|
|
21599
|
-
|
|
21600
|
-
|
|
21601
|
-
|
|
21602
|
-
marginBottom: 6,
|
|
21603
|
-
border: "none",
|
|
21604
|
-
borderRadius: 8,
|
|
21605
|
-
padding: 0,
|
|
21606
|
-
background: "transparent",
|
|
21607
|
-
cursor: "pointer"
|
|
21686
|
+
frame: {
|
|
21687
|
+
flex: 1,
|
|
21688
|
+
minHeight: 0,
|
|
21689
|
+
width: "100%",
|
|
21690
|
+
border: 0,
|
|
21691
|
+
background: "#fff"
|
|
21608
21692
|
},
|
|
21609
|
-
|
|
21610
|
-
|
|
21693
|
+
overlay: {
|
|
21694
|
+
position: "fixed",
|
|
21695
|
+
inset: 0,
|
|
21696
|
+
zIndex: 1100,
|
|
21611
21697
|
display: "grid",
|
|
21612
21698
|
placeItems: "center",
|
|
21613
|
-
|
|
21614
|
-
|
|
21615
|
-
|
|
21616
|
-
background: "var(--dsw-alias-button-primary-fill)",
|
|
21617
|
-
color: "var(--dsw-alias-label-primary-inverted)"
|
|
21699
|
+
padding: 18,
|
|
21700
|
+
background: "rgb(9 19 16 / 56%)",
|
|
21701
|
+
backdropFilter: "blur(5px)"
|
|
21618
21702
|
},
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
minWidth: 0,
|
|
21703
|
+
dialog: {
|
|
21704
|
+
width: "min(460px, 100%)",
|
|
21622
21705
|
overflow: "hidden",
|
|
21623
|
-
|
|
21624
|
-
|
|
21706
|
+
border: "1px solid color-mix(in srgb, var(--dsw-alias-border-l2) 70%, white)",
|
|
21707
|
+
borderRadius: 16,
|
|
21708
|
+
background: "var(--dsw-alias-bg-base)",
|
|
21709
|
+
boxShadow: "0 24px 70px rgb(0 0 0 / 32%)"
|
|
21625
21710
|
},
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
background: "var(--dsw-alias-bg-l2, rgb(0 0 0 / 6%))",
|
|
21631
|
-
color: "var(--dsw-alias-brand-primary)",
|
|
21632
|
-
fontSize: 11,
|
|
21633
|
-
fontWeight: 600
|
|
21711
|
+
hero: {
|
|
21712
|
+
padding: "22px 24px 18px",
|
|
21713
|
+
background: "linear-gradient(135deg, #173329 0%, #29553d 100%)",
|
|
21714
|
+
color: "#f7fbf8"
|
|
21634
21715
|
},
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21716
|
+
eyebrow: {
|
|
21717
|
+
margin: 0,
|
|
21718
|
+
color: "#b9ddc6",
|
|
21719
|
+
fontSize: 11,
|
|
21720
|
+
fontWeight: 700,
|
|
21721
|
+
letterSpacing: ".12em"
|
|
21640
21722
|
},
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
height: 44,
|
|
21647
|
-
borderRadius: "50%",
|
|
21648
|
-
background: "var(--dsw-alias-button-primary-fill)",
|
|
21649
|
-
color: "var(--dsw-alias-label-primary-inverted)"
|
|
21723
|
+
title: {
|
|
21724
|
+
margin: "7px 0 0",
|
|
21725
|
+
fontSize: 21,
|
|
21726
|
+
lineHeight: 1.2,
|
|
21727
|
+
letterSpacing: "-.02em"
|
|
21650
21728
|
},
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
whiteSpace: "nowrap"
|
|
21729
|
+
body: { padding: "20px 24px 22px" },
|
|
21730
|
+
copy: {
|
|
21731
|
+
margin: "0 0 16px",
|
|
21732
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
21733
|
+
fontSize: 13,
|
|
21734
|
+
lineHeight: 1.6
|
|
21658
21735
|
},
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21736
|
+
field: {
|
|
21737
|
+
boxSizing: "border-box",
|
|
21738
|
+
width: "100%",
|
|
21739
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
21740
|
+
borderRadius: 8,
|
|
21741
|
+
padding: "10px 11px",
|
|
21742
|
+
color: "var(--dsw-alias-label-primary)",
|
|
21743
|
+
background: "var(--dsw-alias-bg-base)",
|
|
21744
|
+
font: "inherit",
|
|
21745
|
+
fontSize: 13
|
|
21663
21746
|
},
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21747
|
+
option: {
|
|
21748
|
+
display: "flex",
|
|
21749
|
+
alignItems: "flex-start",
|
|
21750
|
+
gap: 10,
|
|
21751
|
+
padding: 12,
|
|
21752
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
21667
21753
|
borderRadius: 10,
|
|
21668
|
-
|
|
21754
|
+
cursor: "pointer"
|
|
21669
21755
|
},
|
|
21670
|
-
|
|
21671
|
-
|
|
21756
|
+
optionSelected: {
|
|
21757
|
+
borderColor: "var(--dsw-alias-brand-primary)",
|
|
21758
|
+
background: "color-mix(in srgb, var(--dsw-alias-brand-primary) 8%, transparent)"
|
|
21759
|
+
},
|
|
21760
|
+
optionTitle: {
|
|
21761
|
+
display: "block",
|
|
21762
|
+
color: "var(--dsw-alias-label-primary)",
|
|
21763
|
+
fontSize: 13,
|
|
21764
|
+
fontWeight: 650
|
|
21765
|
+
},
|
|
21766
|
+
optionText: {
|
|
21767
|
+
display: "block",
|
|
21768
|
+
marginTop: 3,
|
|
21672
21769
|
color: "var(--dsw-alias-label-secondary)",
|
|
21673
21770
|
fontSize: 12,
|
|
21674
|
-
|
|
21771
|
+
lineHeight: 1.45
|
|
21675
21772
|
},
|
|
21676
|
-
|
|
21773
|
+
error: {
|
|
21774
|
+
margin: "12px 0 0",
|
|
21775
|
+
color: "var(--dsw-alias-state-error-primary)",
|
|
21776
|
+
fontSize: 12,
|
|
21777
|
+
lineHeight: 1.45
|
|
21778
|
+
},
|
|
21779
|
+
actions: {
|
|
21677
21780
|
display: "flex",
|
|
21678
|
-
justifyContent: "
|
|
21679
|
-
gap:
|
|
21680
|
-
|
|
21681
|
-
fontSize: 13
|
|
21781
|
+
justifyContent: "flex-end",
|
|
21782
|
+
gap: 8,
|
|
21783
|
+
marginTop: 20
|
|
21682
21784
|
},
|
|
21683
|
-
|
|
21684
|
-
|
|
21685
|
-
|
|
21686
|
-
|
|
21687
|
-
|
|
21688
|
-
|
|
21689
|
-
|
|
21785
|
+
linkBox: {
|
|
21786
|
+
display: "flex",
|
|
21787
|
+
alignItems: "center",
|
|
21788
|
+
gap: 8,
|
|
21789
|
+
padding: 10,
|
|
21790
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
21791
|
+
borderRadius: 9,
|
|
21792
|
+
background: "var(--dsw-alias-bg-layer-1)"
|
|
21690
21793
|
},
|
|
21691
|
-
|
|
21692
|
-
|
|
21693
|
-
|
|
21694
|
-
|
|
21794
|
+
link: {
|
|
21795
|
+
minWidth: 0,
|
|
21796
|
+
flex: 1,
|
|
21797
|
+
overflow: "hidden",
|
|
21798
|
+
color: "var(--dsw-alias-brand-primary)",
|
|
21799
|
+
fontSize: 12,
|
|
21800
|
+
textOverflow: "ellipsis",
|
|
21801
|
+
whiteSpace: "nowrap"
|
|
21695
21802
|
},
|
|
21696
|
-
|
|
21697
|
-
|
|
21698
|
-
|
|
21699
|
-
|
|
21803
|
+
success: {
|
|
21804
|
+
display: "grid",
|
|
21805
|
+
placeItems: "center",
|
|
21806
|
+
width: 32,
|
|
21807
|
+
height: 32,
|
|
21808
|
+
borderRadius: "50%",
|
|
21809
|
+
background: "#e3f4e8",
|
|
21810
|
+
color: "#237344",
|
|
21811
|
+
fontSize: 18,
|
|
21812
|
+
fontWeight: 700
|
|
21700
21813
|
},
|
|
21701
|
-
|
|
21814
|
+
memberCard: {
|
|
21702
21815
|
display: "flex",
|
|
21816
|
+
gap: 14,
|
|
21703
21817
|
alignItems: "center",
|
|
21704
|
-
|
|
21705
|
-
|
|
21706
|
-
|
|
21707
|
-
borderRadius:
|
|
21708
|
-
background: "var(--dsw-alias-bg-layer-1
|
|
21818
|
+
margin: "14px 0 0",
|
|
21819
|
+
padding: 13,
|
|
21820
|
+
border: "1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 35%, var(--dsw-alias-border-l2))",
|
|
21821
|
+
borderRadius: 11,
|
|
21822
|
+
background: "var(--dsw-alias-bg-layer-1)"
|
|
21709
21823
|
},
|
|
21710
|
-
|
|
21824
|
+
memberQr: {
|
|
21711
21825
|
flex: "none",
|
|
21712
|
-
width:
|
|
21713
|
-
height:
|
|
21714
|
-
borderRadius:
|
|
21826
|
+
width: 96,
|
|
21827
|
+
height: 96,
|
|
21828
|
+
borderRadius: 8,
|
|
21715
21829
|
background: "#fff",
|
|
21716
21830
|
objectFit: "contain"
|
|
21717
21831
|
},
|
|
21718
|
-
|
|
21832
|
+
memberTitle: {
|
|
21719
21833
|
margin: 0,
|
|
21834
|
+
color: "var(--dsw-alias-label-primary)",
|
|
21720
21835
|
fontSize: 13,
|
|
21721
21836
|
fontWeight: 650
|
|
21722
21837
|
},
|
|
21723
|
-
|
|
21724
|
-
margin: "
|
|
21838
|
+
memberText: {
|
|
21839
|
+
margin: "5px 0 0",
|
|
21725
21840
|
color: "var(--dsw-alias-label-secondary)",
|
|
21726
21841
|
fontSize: 12,
|
|
21727
21842
|
lineHeight: 1.55
|
|
21728
21843
|
},
|
|
21729
|
-
|
|
21730
|
-
|
|
21731
|
-
|
|
21732
|
-
|
|
21733
|
-
|
|
21734
|
-
|
|
21735
|
-
|
|
21736
|
-
|
|
21737
|
-
|
|
21738
|
-
borderRadius: 8,
|
|
21739
|
-
padding: "0 14px",
|
|
21740
|
-
background: "transparent",
|
|
21741
|
-
color: "var(--dsw-alias-label-primary)",
|
|
21742
|
-
font: "inherit",
|
|
21743
|
-
fontSize: 13,
|
|
21744
|
-
cursor: "pointer"
|
|
21745
|
-
},
|
|
21746
|
-
danger: {
|
|
21747
|
-
height: 32,
|
|
21748
|
-
border: "none",
|
|
21749
|
-
borderRadius: 8,
|
|
21750
|
-
padding: "0 14px",
|
|
21751
|
-
background: "var(--dsw-alias-state-error-primary)",
|
|
21752
|
-
color: "#fff",
|
|
21753
|
-
font: "inherit",
|
|
21754
|
-
fontSize: 13,
|
|
21755
|
-
fontWeight: 600,
|
|
21756
|
-
cursor: "pointer"
|
|
21757
|
-
},
|
|
21758
|
-
footerRail: {
|
|
21759
|
-
boxSizing: "border-box",
|
|
21760
|
-
display: "grid",
|
|
21761
|
-
placeItems: "center",
|
|
21762
|
-
width: 36,
|
|
21763
|
-
height: 36,
|
|
21764
|
-
marginBottom: 6,
|
|
21765
|
-
border: "none",
|
|
21766
|
-
borderRadius: 8,
|
|
21767
|
-
background: "var(--dsw-alias-button-primary-fill)",
|
|
21768
|
-
color: "var(--dsw-alias-label-primary-inverted)",
|
|
21769
|
-
cursor: "pointer"
|
|
21844
|
+
accountCard: {
|
|
21845
|
+
margin: "0 0 15px",
|
|
21846
|
+
padding: "9px 11px",
|
|
21847
|
+
borderLeft: "3px solid var(--dsw-alias-brand-primary)",
|
|
21848
|
+
borderRadius: 6,
|
|
21849
|
+
background: "var(--dsw-alias-bg-layer-1)",
|
|
21850
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
21851
|
+
fontSize: 12,
|
|
21852
|
+
lineHeight: 1.5
|
|
21770
21853
|
}
|
|
21771
21854
|
};
|
|
21772
|
-
|
|
21773
|
-
|
|
21774
|
-
|
|
21775
|
-
|
|
21776
|
-
|
|
21777
|
-
|
|
21778
|
-
stroke: "currentColor",
|
|
21779
|
-
strokeWidth: 1.5,
|
|
21780
|
-
strokeLinecap: "round",
|
|
21781
|
-
"aria-hidden": true,
|
|
21782
|
-
children: [(0, react_jsx_runtime.jsx)("circle", {
|
|
21783
|
-
cx: "8",
|
|
21784
|
-
cy: "5.5",
|
|
21785
|
-
r: "2.75"
|
|
21786
|
-
}), (0, react_jsx_runtime.jsx)("path", { d: "M2.75 13.5c.6-2.4 2.7-3.9 5.25-3.9s4.65 1.5 5.25 3.9" })]
|
|
21787
|
-
});
|
|
21788
|
-
}
|
|
21789
|
-
function CloseIcon() {
|
|
21790
|
-
return (0, react_jsx_runtime.jsx)("svg", {
|
|
21791
|
-
width: 16,
|
|
21792
|
-
height: 16,
|
|
21793
|
-
viewBox: "0 0 16 16",
|
|
21794
|
-
fill: "none",
|
|
21795
|
-
stroke: "currentColor",
|
|
21796
|
-
strokeWidth: 1.6,
|
|
21797
|
-
strokeLinecap: "round",
|
|
21798
|
-
"aria-hidden": true,
|
|
21799
|
-
children: (0, react_jsx_runtime.jsx)("path", { d: "M4 4l8 8M12 4l-8 8" })
|
|
21800
|
-
});
|
|
21801
|
-
}
|
|
21802
|
-
/** 全局登录弹窗:已登录时不渲染。对话、我的作品等所有需要登录的入口都打开它。 */
|
|
21803
|
-
function LoginDialogOverlay({ remote }) {
|
|
21804
|
-
const open = useDialogOpen();
|
|
21805
|
-
const account = useEdusLogin();
|
|
21806
|
-
const visible = open && account === null;
|
|
21807
|
-
const [busy, setBusy] = (0, react.useState)(false);
|
|
21808
|
-
const close = (0, react.useCallback)(() => {
|
|
21809
|
-
if (!busy) EdusLoginDialog.close();
|
|
21810
|
-
}, [busy]);
|
|
21811
|
-
(0, react.useEffect)(() => {
|
|
21812
|
-
if (!visible) return;
|
|
21813
|
-
const onKey = (event) => {
|
|
21814
|
-
if (event.key === "Escape") close();
|
|
21815
|
-
};
|
|
21816
|
-
window.addEventListener("keydown", onKey);
|
|
21817
|
-
return () => {
|
|
21818
|
-
window.removeEventListener("keydown", onKey);
|
|
21819
|
-
};
|
|
21820
|
-
}, [visible, close]);
|
|
21821
|
-
if (!visible) return null;
|
|
21822
|
-
return (0, react_jsx_runtime.jsx)("div", {
|
|
21823
|
-
role: "dialog",
|
|
21824
|
-
"aria-modal": "true",
|
|
21825
|
-
"aria-labelledby": "edus-login-dialog-title",
|
|
21826
|
-
style: ui.backdrop,
|
|
21827
|
-
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
21828
|
-
style: ui.card,
|
|
21829
|
-
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
21830
|
-
type: "button",
|
|
21831
|
-
"aria-label": "关闭",
|
|
21832
|
-
title: "关闭",
|
|
21833
|
-
style: ui.close,
|
|
21834
|
-
disabled: busy,
|
|
21835
|
-
onClick: close,
|
|
21836
|
-
children: (0, react_jsx_runtime.jsx)(CloseIcon, {})
|
|
21837
|
-
}), (0, react_jsx_runtime.jsx)(EdusLoginPanel, {
|
|
21838
|
-
remote,
|
|
21839
|
-
intro: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)("h2", {
|
|
21840
|
-
id: "edus-login-dialog-title",
|
|
21841
|
-
style: ui.title,
|
|
21842
|
-
children: "登录课成账号"
|
|
21843
|
-
}), (0, react_jsx_runtime.jsx)("p", {
|
|
21844
|
-
style: ui.intro,
|
|
21845
|
-
children: "登录后即可开始 AI 对话,查看和发布你的作品。"
|
|
21846
|
-
})] }),
|
|
21847
|
-
onBusyChange: setBusy,
|
|
21848
|
-
onSuccess: (result) => {
|
|
21849
|
-
EdusAuthStore.set(result);
|
|
21850
|
-
EdusLoginDialog.close();
|
|
21851
|
-
},
|
|
21852
|
-
theme: {
|
|
21853
|
-
field: ui.dialogField,
|
|
21854
|
-
primary: ui.dialogPrimary
|
|
21855
|
-
}
|
|
21856
|
-
})]
|
|
21857
|
-
})
|
|
21858
|
-
});
|
|
21859
|
-
}
|
|
21860
|
-
/** 输入框上方的未登录横幅。 */
|
|
21861
|
-
function LoginDockBanner() {
|
|
21862
|
-
if (useEdusLogin() !== null) return null;
|
|
21863
|
-
return (0, react_jsx_runtime.jsx)("div", {
|
|
21864
|
-
style: ui.dock,
|
|
21865
|
-
children: (0, react_jsx_runtime.jsxs)("div", {
|
|
21866
|
-
style: ui.banner,
|
|
21867
|
-
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
21868
|
-
style: ui.bannerText,
|
|
21869
|
-
children: "登录课成账号后即可开始对话"
|
|
21870
|
-
}), (0, react_jsx_runtime.jsx)("button", {
|
|
21871
|
-
type: "button",
|
|
21872
|
-
style: ui.primary,
|
|
21873
|
-
onClick: EdusLoginDialog.open,
|
|
21874
|
-
children: "登录"
|
|
21875
|
-
})]
|
|
21876
|
-
})
|
|
21877
|
-
});
|
|
21878
|
-
}
|
|
21879
|
-
/** 侧边栏底部的账号入口:未登录为登录按钮,已登录显示当前账号;收起为窄栏时只显示图标。 */
|
|
21880
|
-
function LoginFooterAction({ wide }) {
|
|
21881
|
-
const account = useEdusLogin();
|
|
21882
|
-
if (account === null) return wide ? (0, react_jsx_runtime.jsxs)("button", {
|
|
21883
|
-
type: "button",
|
|
21884
|
-
style: ui.footer,
|
|
21885
|
-
onClick: EdusLoginDialog.open,
|
|
21886
|
-
children: [(0, react_jsx_runtime.jsx)(UserIcon, {}), "登录课成账号"]
|
|
21887
|
-
}) : (0, react_jsx_runtime.jsx)("button", {
|
|
21888
|
-
type: "button",
|
|
21889
|
-
title: "登录课成账号",
|
|
21890
|
-
"aria-label": "登录课成账号",
|
|
21891
|
-
style: ui.footerRail,
|
|
21892
|
-
onClick: EdusLoginDialog.open,
|
|
21893
|
-
children: (0, react_jsx_runtime.jsx)(UserIcon, {})
|
|
21894
|
-
});
|
|
21895
|
-
const name = displayName(account);
|
|
21896
|
-
return wide ? (0, react_jsx_runtime.jsxs)("button", {
|
|
21897
|
-
type: "button",
|
|
21898
|
-
title: "账号信息",
|
|
21899
|
-
style: ui.account,
|
|
21900
|
-
onClick: EdusAccountDialog.open,
|
|
21901
|
-
children: [
|
|
21902
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
21903
|
-
style: ui.avatar,
|
|
21904
|
-
children: (0, react_jsx_runtime.jsx)(UserIcon, {})
|
|
21905
|
-
}),
|
|
21906
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
21907
|
-
style: ui.accountName,
|
|
21908
|
-
children: name
|
|
21909
|
-
}),
|
|
21910
|
-
account.isVip && account.vipLevelName && (0, react_jsx_runtime.jsx)("span", {
|
|
21911
|
-
style: ui.badge,
|
|
21912
|
-
children: account.vipLevelName
|
|
21913
|
-
})
|
|
21914
|
-
]
|
|
21915
|
-
}) : (0, react_jsx_runtime.jsx)("button", {
|
|
21916
|
-
type: "button",
|
|
21917
|
-
title: `${name} · 账号信息`,
|
|
21918
|
-
"aria-label": "账号信息",
|
|
21919
|
-
style: ui.accountRail,
|
|
21920
|
-
onClick: EdusAccountDialog.open,
|
|
21921
|
-
children: (0, react_jsx_runtime.jsx)("span", {
|
|
21922
|
-
style: ui.avatar,
|
|
21923
|
-
children: (0, react_jsx_runtime.jsx)(UserIcon, {})
|
|
21924
|
-
})
|
|
21855
|
+
/** 普通报错直接展示文案;会员相关的报错额外给出客服二维码。 */
|
|
21856
|
+
function PublishError({ message }) {
|
|
21857
|
+
if (message === "") return null;
|
|
21858
|
+
if (!message.includes(MEMBERSHIP_HINT)) return (0, react_jsx_runtime.jsx)("p", {
|
|
21859
|
+
style: styles$1.error,
|
|
21860
|
+
children: message
|
|
21925
21861
|
});
|
|
21926
|
-
}
|
|
21927
|
-
/** 客服(技术支持)微信二维码:开通会员或遇到问题时扫码添加。 */
|
|
21928
|
-
const SUPPORT_QR = "https://cdn.juzhenai.cn/assets/jishu-weixin-qrcode.jpg";
|
|
21929
|
-
function maskPhone(phone) {
|
|
21930
|
-
return /^\d{11}$/.test(phone) ? `${phone.slice(0, 3)}****${phone.slice(7)}` : phone;
|
|
21931
|
-
}
|
|
21932
|
-
function displayName(account) {
|
|
21933
|
-
return account.title || maskPhone(account.phone);
|
|
21934
|
-
}
|
|
21935
|
-
function formatTime(value) {
|
|
21936
|
-
if (!value) return "—";
|
|
21937
|
-
const date = new Date(value);
|
|
21938
|
-
if (Number.isNaN(date.getTime())) return value;
|
|
21939
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
21940
|
-
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
21941
|
-
}
|
|
21942
|
-
/** 取整 */
|
|
21943
|
-
function formatPoints(value) {
|
|
21944
|
-
const amount = Number(value);
|
|
21945
|
-
return value === void 0 || value === "" || Number.isNaN(amount) ? "—" : Math.round(amount).toLocaleString("zh-CN");
|
|
21946
|
-
}
|
|
21947
|
-
function Row({ label, value }) {
|
|
21948
21862
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
21949
|
-
style:
|
|
21950
|
-
children: [(0, react_jsx_runtime.jsx)("
|
|
21951
|
-
|
|
21952
|
-
|
|
21953
|
-
|
|
21863
|
+
style: styles$1.memberCard,
|
|
21864
|
+
children: [(0, react_jsx_runtime.jsx)("img", {
|
|
21865
|
+
alt: "客服微信二维码",
|
|
21866
|
+
src: SERVICE_QR,
|
|
21867
|
+
style: styles$1.memberQr
|
|
21868
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
21869
|
+
style: { minWidth: 0 },
|
|
21870
|
+
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
21871
|
+
style: styles$1.memberTitle,
|
|
21872
|
+
children: message
|
|
21873
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
21874
|
+
style: styles$1.memberText,
|
|
21875
|
+
children: "该功能需要开通会员后使用。请用微信扫描左侧二维码添加客服咨询开通。"
|
|
21876
|
+
})]
|
|
21877
|
+
})]
|
|
21954
21878
|
});
|
|
21955
21879
|
}
|
|
21956
|
-
/**
|
|
21957
|
-
function
|
|
21958
|
-
const open = useAccountOpen();
|
|
21880
|
+
/** An extension-priority document body: native right-preview ergonomics plus a complete edus publishing flow. */
|
|
21881
|
+
function HtmlPublishPreview({ content, resourceAddress, remote }) {
|
|
21959
21882
|
const account = useEdusLogin();
|
|
21960
|
-
const
|
|
21961
|
-
const [
|
|
21883
|
+
const [stage, setStage] = (0, react.useState)("closed");
|
|
21884
|
+
const [destination, setDestination] = (0, react.useState)("new");
|
|
21885
|
+
const [title, setTitle] = (0, react.useState)("");
|
|
21886
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
21962
21887
|
const [error, setError] = (0, react.useState)("");
|
|
21963
|
-
const [
|
|
21964
|
-
const
|
|
21965
|
-
|
|
21966
|
-
|
|
21967
|
-
|
|
21968
|
-
|
|
21969
|
-
}, [
|
|
21970
|
-
const
|
|
21888
|
+
const [shareUrl, setShareUrl] = (0, react.useState)(null);
|
|
21889
|
+
const [copied, setCopied] = (0, react.useState)(false);
|
|
21890
|
+
const ref = (0, react.useMemo)(() => fileRef(resourceAddress), [resourceAddress]);
|
|
21891
|
+
const source = (0, react.useMemo)(() => {
|
|
21892
|
+
if (content.kind === "bytes") return new TextDecoder().decode(content.data);
|
|
21893
|
+
return content.kind === "text" ? content.text : "";
|
|
21894
|
+
}, [content]);
|
|
21895
|
+
const marker = (0, react.useMemo)(() => extractMarker(source), [source]);
|
|
21896
|
+
const currentAvailable = marker !== null && marker.owner === account?.phone;
|
|
21897
|
+
const [awaitingLogin, setAwaitingLogin] = (0, react.useState)(false);
|
|
21898
|
+
const loginOpen = (0, react.useSyncExternalStore)(EdusLoginDialog.subscribe, EdusLoginDialog.getSnapshot, () => false);
|
|
21971
21899
|
(0, react.useEffect)(() => {
|
|
21972
|
-
if (!
|
|
21973
|
-
|
|
21900
|
+
if (!awaitingLogin) return;
|
|
21901
|
+
if (account !== null) {
|
|
21902
|
+
setAwaitingLogin(false);
|
|
21903
|
+
setDestination(marker !== null && marker.owner === account.phone ? "current" : "new");
|
|
21904
|
+
setStage("destination");
|
|
21905
|
+
} else if (!loginOpen) setAwaitingLogin(false);
|
|
21906
|
+
}, [
|
|
21907
|
+
awaitingLogin,
|
|
21908
|
+
account,
|
|
21909
|
+
loginOpen,
|
|
21910
|
+
marker
|
|
21911
|
+
]);
|
|
21912
|
+
const requestLogin = (notice) => {
|
|
21913
|
+
setStage("closed");
|
|
21914
|
+
setAwaitingLogin(true);
|
|
21915
|
+
EdusLoginDialog.open(notice);
|
|
21916
|
+
};
|
|
21917
|
+
const open = async () => {
|
|
21974
21918
|
setError("");
|
|
21975
|
-
|
|
21976
|
-
|
|
21977
|
-
|
|
21978
|
-
|
|
21979
|
-
|
|
21980
|
-
|
|
21981
|
-
|
|
21982
|
-
|
|
21983
|
-
|
|
21984
|
-
|
|
21985
|
-
|
|
21986
|
-
|
|
21919
|
+
setShareUrl(null);
|
|
21920
|
+
setCopied(false);
|
|
21921
|
+
setTitle(ref === null ? "" : basename(ref.path).replace(/\.html?$/i, ""));
|
|
21922
|
+
const stored = EdusAuthStore.getSnapshot();
|
|
21923
|
+
if (stored === null) {
|
|
21924
|
+
requestLogin();
|
|
21925
|
+
return;
|
|
21926
|
+
}
|
|
21927
|
+
setBusy(true);
|
|
21928
|
+
setStage("checking");
|
|
21929
|
+
try {
|
|
21930
|
+
const refreshed = await remote.loginInfo(stored.token);
|
|
21931
|
+
EdusAuthStore.set(refreshed);
|
|
21932
|
+
setDestination(marker !== null && marker.owner === refreshed.phone ? "current" : "new");
|
|
21933
|
+
setStage("destination");
|
|
21934
|
+
} catch {
|
|
21935
|
+
EdusAuthStore.logout();
|
|
21936
|
+
requestLogin("登录状态已失效,请重新登录。");
|
|
21937
|
+
} finally {
|
|
21938
|
+
setBusy(false);
|
|
21939
|
+
}
|
|
21940
|
+
};
|
|
21941
|
+
const close = () => {
|
|
21942
|
+
if (!busy) setStage("closed");
|
|
21943
|
+
};
|
|
21944
|
+
const submitPublish = (0, react.useCallback)(async () => {
|
|
21945
|
+
if (ref === null || account === null) return;
|
|
21946
|
+
const newWork = destination === "new";
|
|
21947
|
+
const publishTitle = title.trim();
|
|
21948
|
+
if (newWork && publishTitle === "") {
|
|
21949
|
+
setError("请为新作品填写标题。");
|
|
21950
|
+
return;
|
|
21951
|
+
}
|
|
21952
|
+
setBusy(true);
|
|
21953
|
+
setError("");
|
|
21954
|
+
try {
|
|
21955
|
+
const result = await remote.publishFile(account.token, ref.sessionId, ref.path, account.phone, publishTitle, newWork);
|
|
21956
|
+
if (result.shareUrl === null) throw new Error("发布完成,但未返回分享链接。");
|
|
21957
|
+
setShareUrl(result.shareUrl);
|
|
21958
|
+
setStage("success");
|
|
21959
|
+
} catch (reason) {
|
|
21960
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
21961
|
+
} finally {
|
|
21962
|
+
setBusy(false);
|
|
21963
|
+
}
|
|
21987
21964
|
}, [
|
|
21988
|
-
|
|
21989
|
-
|
|
21990
|
-
|
|
21965
|
+
account,
|
|
21966
|
+
destination,
|
|
21967
|
+
ref,
|
|
21968
|
+
remote,
|
|
21969
|
+
title
|
|
21991
21970
|
]);
|
|
21992
|
-
|
|
21993
|
-
if (
|
|
21994
|
-
|
|
21995
|
-
|
|
21996
|
-
|
|
21997
|
-
|
|
21998
|
-
|
|
21999
|
-
|
|
22000
|
-
|
|
22001
|
-
|
|
22002
|
-
|
|
22003
|
-
|
|
22004
|
-
|
|
22005
|
-
|
|
22006
|
-
|
|
22007
|
-
|
|
22008
|
-
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22012
|
-
|
|
22013
|
-
|
|
22014
|
-
|
|
22015
|
-
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
22020
|
-
|
|
22021
|
-
|
|
22022
|
-
|
|
22023
|
-
|
|
22024
|
-
|
|
22025
|
-
|
|
22026
|
-
|
|
22027
|
-
|
|
22028
|
-
|
|
22029
|
-
|
|
22030
|
-
|
|
22031
|
-
|
|
22032
|
-
|
|
22033
|
-
|
|
22034
|
-
|
|
22035
|
-
children: displayName(account)
|
|
22036
|
-
}), (0, react_jsx_runtime.jsxs)("p", {
|
|
22037
|
-
style: ui.profileSub,
|
|
22038
|
-
children: [maskPhone(account.phone), account.isAdmin ? " · 管理员" : ""]
|
|
22039
|
-
})]
|
|
22040
|
-
})]
|
|
22041
|
-
}),
|
|
22042
|
-
refreshing && (0, react_jsx_runtime.jsx)("p", {
|
|
22043
|
-
style: ui.status,
|
|
22044
|
-
role: "status",
|
|
22045
|
-
children: "正在刷新账号信息…"
|
|
22046
|
-
}),
|
|
22047
|
-
error !== "" && (0, react_jsx_runtime.jsx)("p", {
|
|
22048
|
-
style: ui.errorText,
|
|
22049
|
-
children: error
|
|
22050
|
-
}),
|
|
22051
|
-
(0, react_jsx_runtime.jsxs)("section", {
|
|
22052
|
-
style: ui.section,
|
|
22053
|
-
children: [
|
|
22054
|
-
(0, react_jsx_runtime.jsx)("h3", {
|
|
22055
|
-
style: ui.sectionTitle,
|
|
22056
|
-
children: "会员"
|
|
22057
|
-
}),
|
|
22058
|
-
(0, react_jsx_runtime.jsx)(Row, {
|
|
22059
|
-
label: "当前版本",
|
|
22060
|
-
value: account.isVip ? account.vipLevelName || `VIP ${account.vipLevel}` : "未开通"
|
|
22061
|
-
}),
|
|
22062
|
-
account.isVip && (0, react_jsx_runtime.jsx)(Row, {
|
|
22063
|
-
label: "到期时间",
|
|
22064
|
-
value: formatTime(account.vipEndTime)
|
|
22065
|
-
}),
|
|
22066
|
-
account.llmStatus !== void 0 && account.llmStatus !== null && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(Row, {
|
|
22067
|
-
label: "本月已用",
|
|
22068
|
-
value: limit > 0 ? `${formatPoints(account.llmMonthCost)} / ${formatPoints(limit)} 积分` : `${formatPoints(account.llmMonthCost)} 积分`
|
|
22069
|
-
}), limit > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
22070
|
-
style: ui.meter,
|
|
22071
|
-
"aria-hidden": true,
|
|
22072
|
-
children: (0, react_jsx_runtime.jsx)("div", { style: {
|
|
22073
|
-
width: `${ratio * 100}%`,
|
|
22074
|
-
height: "100%",
|
|
22075
|
-
background: ratio >= .9 ? "var(--dsw-alias-state-error-primary)" : "var(--dsw-alias-brand-primary)"
|
|
22076
|
-
} })
|
|
22077
|
-
})] }),
|
|
22078
|
-
account.isVip && limit === 0 && (0, react_jsx_runtime.jsx)(Row, {
|
|
22079
|
-
label: "每月额度",
|
|
22080
|
-
value: "不限"
|
|
22081
|
-
})
|
|
22082
|
-
]
|
|
22083
|
-
}),
|
|
22084
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
22085
|
-
style: ui.support,
|
|
22086
|
-
children: [(0, react_jsx_runtime.jsx)("img", {
|
|
22087
|
-
alt: "客服微信二维码",
|
|
22088
|
-
src: SUPPORT_QR,
|
|
22089
|
-
style: ui.supportQr
|
|
22090
|
-
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
22091
|
-
style: { minWidth: 0 },
|
|
21971
|
+
const copy = async () => {
|
|
21972
|
+
if (shareUrl === null) return;
|
|
21973
|
+
try {
|
|
21974
|
+
await navigator.clipboard.writeText(shareUrl);
|
|
21975
|
+
setCopied(true);
|
|
21976
|
+
} catch {
|
|
21977
|
+
setError("复制失败,请手动复制链接。");
|
|
21978
|
+
}
|
|
21979
|
+
};
|
|
21980
|
+
if (content.kind !== "bytes") return null;
|
|
21981
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
21982
|
+
style: styles$1.root,
|
|
21983
|
+
"data-edus-html-preview": true,
|
|
21984
|
+
children: [
|
|
21985
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
21986
|
+
style: styles$1.bar,
|
|
21987
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
21988
|
+
style: styles$1.primary,
|
|
21989
|
+
onClick: () => void open(),
|
|
21990
|
+
children: "发布网页"
|
|
21991
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
21992
|
+
style: styles$1.account,
|
|
21993
|
+
children: account === null ? "尚未登录" : `${account.title || "当前账号"} · ${account.phone}`
|
|
21994
|
+
})]
|
|
21995
|
+
}),
|
|
21996
|
+
(0, react_jsx_runtime.jsx)("iframe", {
|
|
21997
|
+
title: "HTML 网页预览",
|
|
21998
|
+
sandbox: "allow-scripts",
|
|
21999
|
+
srcDoc: source,
|
|
22000
|
+
style: styles$1.frame
|
|
22001
|
+
}),
|
|
22002
|
+
stage !== "closed" && (0, react_jsx_runtime.jsx)("div", {
|
|
22003
|
+
style: styles$1.overlay,
|
|
22004
|
+
role: "presentation",
|
|
22005
|
+
onMouseDown: close,
|
|
22006
|
+
children: (0, react_jsx_runtime.jsxs)("section", {
|
|
22007
|
+
style: styles$1.dialog,
|
|
22008
|
+
role: "dialog",
|
|
22009
|
+
"aria-modal": "true",
|
|
22010
|
+
"aria-labelledby": "edus-publish-title",
|
|
22011
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
22012
|
+
children: [(0, react_jsx_runtime.jsxs)("header", {
|
|
22013
|
+
style: styles$1.hero,
|
|
22092
22014
|
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
22093
|
-
style:
|
|
22094
|
-
children: "
|
|
22095
|
-
}), (0, react_jsx_runtime.jsx)("
|
|
22096
|
-
|
|
22097
|
-
|
|
22015
|
+
style: styles$1.eyebrow,
|
|
22016
|
+
children: "COURSE · PUBLISH"
|
|
22017
|
+
}), (0, react_jsx_runtime.jsx)("h2", {
|
|
22018
|
+
id: "edus-publish-title",
|
|
22019
|
+
style: styles$1.title,
|
|
22020
|
+
children: stage === "checking" ? "正在确认账号" : stage === "success" ? "作品已成功发布" : "选择发布目标"
|
|
22098
22021
|
})]
|
|
22022
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
22023
|
+
style: styles$1.body,
|
|
22024
|
+
children: [
|
|
22025
|
+
stage === "checking" && (0, react_jsx_runtime.jsx)("p", {
|
|
22026
|
+
style: styles$1.copy,
|
|
22027
|
+
children: "正在通过课成账号服务确认当前登录状态…"
|
|
22028
|
+
}),
|
|
22029
|
+
stage === "destination" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
22030
|
+
account !== null && (0, react_jsx_runtime.jsxs)("p", {
|
|
22031
|
+
style: styles$1.accountCard,
|
|
22032
|
+
children: [
|
|
22033
|
+
"当前账号:",
|
|
22034
|
+
(0, react_jsx_runtime.jsx)("strong", { children: account.title || account.phone }),
|
|
22035
|
+
account.title !== "" ? `(${account.phone})` : ""
|
|
22036
|
+
]
|
|
22037
|
+
}),
|
|
22038
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
22039
|
+
style: styles$1.copy,
|
|
22040
|
+
children: "请选择本次内容的归属。发布会把当前 HTML 文件的最新内容写入所选作品。"
|
|
22041
|
+
}),
|
|
22042
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
22043
|
+
style: {
|
|
22044
|
+
display: "grid",
|
|
22045
|
+
gap: 9
|
|
22046
|
+
},
|
|
22047
|
+
children: [currentAvailable && (0, react_jsx_runtime.jsxs)("label", {
|
|
22048
|
+
style: {
|
|
22049
|
+
...styles$1.option,
|
|
22050
|
+
...destination === "current" ? styles$1.optionSelected : {}
|
|
22051
|
+
},
|
|
22052
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
22053
|
+
name: "destination",
|
|
22054
|
+
type: "radio",
|
|
22055
|
+
checked: destination === "current",
|
|
22056
|
+
onChange: () => setDestination("current")
|
|
22057
|
+
}), (0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
22058
|
+
style: styles$1.optionTitle,
|
|
22059
|
+
children: "更新已关联作品"
|
|
22060
|
+
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
22061
|
+
style: styles$1.optionText,
|
|
22062
|
+
children: [
|
|
22063
|
+
"继续发布到当前文件绑定的作品(",
|
|
22064
|
+
marker.id.slice(0, 8),
|
|
22065
|
+
"…)。"
|
|
22066
|
+
]
|
|
22067
|
+
})] })]
|
|
22068
|
+
}), (0, react_jsx_runtime.jsxs)("label", {
|
|
22069
|
+
style: {
|
|
22070
|
+
...styles$1.option,
|
|
22071
|
+
...destination === "new" ? styles$1.optionSelected : {}
|
|
22072
|
+
},
|
|
22073
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
22074
|
+
name: "destination",
|
|
22075
|
+
type: "radio",
|
|
22076
|
+
checked: destination === "new",
|
|
22077
|
+
onChange: () => setDestination("new")
|
|
22078
|
+
}), (0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("span", {
|
|
22079
|
+
style: styles$1.optionTitle,
|
|
22080
|
+
children: "创建新作品并发布"
|
|
22081
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
22082
|
+
style: styles$1.optionText,
|
|
22083
|
+
children: "创建新的分享页,并把当前文件重新关联到该作品。"
|
|
22084
|
+
})] })]
|
|
22085
|
+
})]
|
|
22086
|
+
}),
|
|
22087
|
+
destination === "new" && (0, react_jsx_runtime.jsxs)("div", {
|
|
22088
|
+
style: { marginTop: 14 },
|
|
22089
|
+
children: [(0, react_jsx_runtime.jsx)("label", {
|
|
22090
|
+
style: {
|
|
22091
|
+
display: "block",
|
|
22092
|
+
marginBottom: 6,
|
|
22093
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
22094
|
+
fontSize: 12
|
|
22095
|
+
},
|
|
22096
|
+
children: "作品标题"
|
|
22097
|
+
}), (0, react_jsx_runtime.jsx)("input", {
|
|
22098
|
+
style: styles$1.field,
|
|
22099
|
+
autoFocus: true,
|
|
22100
|
+
value: title,
|
|
22101
|
+
placeholder: "例如:春季招生落地页",
|
|
22102
|
+
onChange: (event) => setTitle(event.target.value)
|
|
22103
|
+
})]
|
|
22104
|
+
}),
|
|
22105
|
+
(0, react_jsx_runtime.jsx)(PublishError, { message: error }),
|
|
22106
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
22107
|
+
style: styles$1.actions,
|
|
22108
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
22109
|
+
style: styles$1.button,
|
|
22110
|
+
disabled: busy,
|
|
22111
|
+
onClick: close,
|
|
22112
|
+
children: "取消"
|
|
22113
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
22114
|
+
style: styles$1.primary,
|
|
22115
|
+
disabled: busy,
|
|
22116
|
+
onClick: () => void submitPublish(),
|
|
22117
|
+
children: busy ? "发布中…" : destination === "new" ? "创建并发布" : "更新并发布"
|
|
22118
|
+
})]
|
|
22119
|
+
})
|
|
22120
|
+
] }),
|
|
22121
|
+
stage === "success" && shareUrl !== null && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
22122
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
22123
|
+
style: {
|
|
22124
|
+
display: "flex",
|
|
22125
|
+
gap: 11,
|
|
22126
|
+
alignItems: "center",
|
|
22127
|
+
marginBottom: 14
|
|
22128
|
+
},
|
|
22129
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
22130
|
+
style: styles$1.success,
|
|
22131
|
+
children: "✓"
|
|
22132
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
22133
|
+
style: {
|
|
22134
|
+
...styles$1.copy,
|
|
22135
|
+
margin: 0
|
|
22136
|
+
},
|
|
22137
|
+
children: "作品已可通过分享链接访问。链接中的内容为本次发布版本。"
|
|
22138
|
+
})]
|
|
22139
|
+
}),
|
|
22140
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
22141
|
+
style: styles$1.linkBox,
|
|
22142
|
+
children: [(0, react_jsx_runtime.jsx)("a", {
|
|
22143
|
+
style: styles$1.link,
|
|
22144
|
+
href: shareUrl,
|
|
22145
|
+
target: "_blank",
|
|
22146
|
+
rel: "noreferrer",
|
|
22147
|
+
title: shareUrl,
|
|
22148
|
+
children: shareUrl
|
|
22149
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
22150
|
+
style: styles$1.button,
|
|
22151
|
+
onClick: () => void copy(),
|
|
22152
|
+
children: copied ? "已复制" : "复制"
|
|
22153
|
+
})]
|
|
22154
|
+
}),
|
|
22155
|
+
error !== "" && (0, react_jsx_runtime.jsx)("p", {
|
|
22156
|
+
style: styles$1.error,
|
|
22157
|
+
children: error
|
|
22158
|
+
}),
|
|
22159
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
22160
|
+
style: styles$1.actions,
|
|
22161
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
22162
|
+
style: styles$1.primary,
|
|
22163
|
+
onClick: close,
|
|
22164
|
+
children: "完成"
|
|
22165
|
+
})
|
|
22166
|
+
})
|
|
22167
|
+
] })
|
|
22168
|
+
]
|
|
22099
22169
|
})]
|
|
22100
|
-
}),
|
|
22101
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
22102
|
-
style: ui.dialogActions,
|
|
22103
|
-
children: confirmLogout ? (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
22104
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
22105
|
-
style: {
|
|
22106
|
-
alignSelf: "center",
|
|
22107
|
-
marginRight: "auto",
|
|
22108
|
-
fontSize: 13
|
|
22109
|
-
},
|
|
22110
|
-
children: "确定退出登录?"
|
|
22111
|
-
}),
|
|
22112
|
-
(0, react_jsx_runtime.jsx)("button", {
|
|
22113
|
-
type: "button",
|
|
22114
|
-
style: ui.quiet,
|
|
22115
|
-
onClick: () => setConfirmLogout(false),
|
|
22116
|
-
children: "取消"
|
|
22117
|
-
}),
|
|
22118
|
-
(0, react_jsx_runtime.jsx)("button", {
|
|
22119
|
-
type: "button",
|
|
22120
|
-
style: ui.danger,
|
|
22121
|
-
onClick: () => {
|
|
22122
|
-
EdusAuthStore.logout();
|
|
22123
|
-
close();
|
|
22124
|
-
},
|
|
22125
|
-
children: "退出"
|
|
22126
|
-
})
|
|
22127
|
-
] }) : (0, react_jsx_runtime.jsx)("button", {
|
|
22128
|
-
type: "button",
|
|
22129
|
-
style: ui.quiet,
|
|
22130
|
-
onClick: () => setConfirmLogout(true),
|
|
22131
|
-
children: "退出登录"
|
|
22132
|
-
})
|
|
22133
22170
|
})
|
|
22134
|
-
|
|
22135
|
-
|
|
22171
|
+
})
|
|
22172
|
+
]
|
|
22136
22173
|
});
|
|
22137
22174
|
}
|
|
22138
22175
|
//#endregion
|
|
22139
22176
|
//#region lib/types/client/MyWorksPanel.js
|
|
22140
|
-
const PAGE_SIZE =
|
|
22177
|
+
const PAGE_SIZE = 20;
|
|
22141
22178
|
function Icon({ name, size = 16 }) {
|
|
22142
22179
|
return (0, react_jsx_runtime.jsx)("svg", {
|
|
22143
22180
|
"aria-hidden": "true",
|
|
@@ -22337,14 +22374,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
22337
22374
|
fontSize: 13,
|
|
22338
22375
|
textAlign: "center"
|
|
22339
22376
|
},
|
|
22340
|
-
|
|
22377
|
+
more: {
|
|
22341
22378
|
display: "flex",
|
|
22342
22379
|
alignItems: "center",
|
|
22343
|
-
justifyContent: "
|
|
22344
|
-
gap:
|
|
22345
|
-
|
|
22346
|
-
|
|
22347
|
-
color: "var(--dsw-alias-label-
|
|
22380
|
+
justifyContent: "center",
|
|
22381
|
+
gap: 8,
|
|
22382
|
+
minHeight: 48,
|
|
22383
|
+
marginTop: 16,
|
|
22384
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
22348
22385
|
fontSize: 12
|
|
22349
22386
|
},
|
|
22350
22387
|
login: {
|
|
@@ -22404,7 +22441,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
22404
22441
|
size
|
|
22405
22442
|
});
|
|
22406
22443
|
}
|
|
22407
|
-
/**
|
|
22444
|
+
/** 主列的「我的作品」页:登录后展示当前账号发布过的网页作品,滚动到底部自动加载下一页。 */
|
|
22408
22445
|
function MyWorksPanel({ remote }) {
|
|
22409
22446
|
const account = useEdusLogin();
|
|
22410
22447
|
const [list, setList] = (0, react.useState)([]);
|
|
@@ -22413,26 +22450,81 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
22413
22450
|
const [searchInput, setSearchInput] = (0, react.useState)("");
|
|
22414
22451
|
const [search, setSearch] = (0, react.useState)("");
|
|
22415
22452
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
22453
|
+
const [loadingMore, setLoadingMore] = (0, react.useState)(false);
|
|
22416
22454
|
const [sharing, setSharing] = (0, react.useState)(null);
|
|
22417
22455
|
const [error, setError] = (0, react.useState)("");
|
|
22418
22456
|
const [notice, setNotice] = (0, react.useState)("");
|
|
22419
|
-
const
|
|
22457
|
+
const hasMore = list.length < total;
|
|
22458
|
+
const token = account?.token;
|
|
22459
|
+
const bodyRef = (0, react.useRef)(null);
|
|
22460
|
+
const sentinelRef = (0, react.useRef)(null);
|
|
22461
|
+
const requestRef = (0, react.useRef)(0);
|
|
22462
|
+
/** 第 1 页替换列表并回到顶部,后续页追加到末尾。 */
|
|
22420
22463
|
const load = (0, react.useCallback)(async (token, nextPage, nextSearch) => {
|
|
22421
|
-
|
|
22464
|
+
const id = ++requestRef.current;
|
|
22465
|
+
const append = nextPage > 1;
|
|
22466
|
+
if (append) setLoadingMore(true);
|
|
22467
|
+
else {
|
|
22468
|
+
setLoading(true);
|
|
22469
|
+
setLoadingMore(false);
|
|
22470
|
+
bodyRef.current?.scrollTo({ top: 0 });
|
|
22471
|
+
}
|
|
22422
22472
|
setError("");
|
|
22423
|
-
setNotice("");
|
|
22473
|
+
if (!append) setNotice("");
|
|
22424
22474
|
try {
|
|
22425
22475
|
const result = await remote.htmlList(token, nextPage, PAGE_SIZE, nextSearch || void 0);
|
|
22426
|
-
|
|
22427
|
-
|
|
22476
|
+
if (id !== requestRef.current) return;
|
|
22477
|
+
setList((prev) => {
|
|
22478
|
+
if (!append) return result.list;
|
|
22479
|
+
const seen = new Set(prev.map((work) => work.id));
|
|
22480
|
+
return [...prev, ...result.list.filter((work) => !seen.has(work.id))];
|
|
22481
|
+
});
|
|
22482
|
+
setTotal(append && result.list.length === 0 ? 0 : result.total);
|
|
22428
22483
|
setPage(result.page);
|
|
22429
22484
|
setSearch(nextSearch);
|
|
22430
22485
|
} catch (reason) {
|
|
22486
|
+
if (id !== requestRef.current) return;
|
|
22431
22487
|
setError(reason instanceof Error ? reason.message : String(reason));
|
|
22432
22488
|
} finally {
|
|
22433
|
-
|
|
22489
|
+
if (id === requestRef.current) {
|
|
22490
|
+
setLoading(false);
|
|
22491
|
+
setLoadingMore(false);
|
|
22492
|
+
}
|
|
22434
22493
|
}
|
|
22435
22494
|
}, [remote]);
|
|
22495
|
+
const loadMore = (0, react.useCallback)(() => {
|
|
22496
|
+
if (token === void 0 || loading || loadingMore || !hasMore) return;
|
|
22497
|
+
load(token, page + 1, search);
|
|
22498
|
+
}, [
|
|
22499
|
+
hasMore,
|
|
22500
|
+
load,
|
|
22501
|
+
loading,
|
|
22502
|
+
loadingMore,
|
|
22503
|
+
page,
|
|
22504
|
+
search,
|
|
22505
|
+
token
|
|
22506
|
+
]);
|
|
22507
|
+
/**
|
|
22508
|
+
* 哨兵元素进入滚动区可视范围(预留 200px)时加载下一页。依赖变化会重建观察器,
|
|
22509
|
+
* observe() 会立即回报一次当前状态,所以首屏内容不足一屏时也会继续补页。
|
|
22510
|
+
* 出错后停止自动加载,改由底部的重试按钮触发,避免失败请求循环。
|
|
22511
|
+
*/
|
|
22512
|
+
(0, react.useEffect)(() => {
|
|
22513
|
+
const root = bodyRef.current, target = sentinelRef.current;
|
|
22514
|
+
if (root === null || target === null || error !== "") return;
|
|
22515
|
+
const observer = new IntersectionObserver((entries) => {
|
|
22516
|
+
if (entries.some((entry) => entry.isIntersecting)) loadMore();
|
|
22517
|
+
}, {
|
|
22518
|
+
root,
|
|
22519
|
+
rootMargin: "0px 0px 200px 0px"
|
|
22520
|
+
});
|
|
22521
|
+
observer.observe(target);
|
|
22522
|
+
return () => observer.disconnect();
|
|
22523
|
+
}, [
|
|
22524
|
+
error,
|
|
22525
|
+
loadMore,
|
|
22526
|
+
list.length
|
|
22527
|
+
]);
|
|
22436
22528
|
const share = async (work, action) => {
|
|
22437
22529
|
if (account === null) return;
|
|
22438
22530
|
const popup = action === "open" ? window.open("about:blank", "_blank") : null;
|
|
@@ -22461,17 +22553,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
22461
22553
|
* 这也顺带把过期 token 挡在渲染之前。登录在统一弹窗里完成,跟随 token 变化
|
|
22462
22554
|
* 重新拉取,弹窗登录成功后列表随即出现。
|
|
22463
22555
|
*/
|
|
22464
|
-
const token = account?.token;
|
|
22465
22556
|
(0, react.useEffect)(() => {
|
|
22466
22557
|
setNotice("");
|
|
22467
22558
|
const stored = EdusAuthStore.getSnapshot();
|
|
22468
22559
|
if (stored === null) {
|
|
22560
|
+
requestRef.current++;
|
|
22469
22561
|
setList([]);
|
|
22470
22562
|
setTotal(0);
|
|
22471
22563
|
setPage(1);
|
|
22472
22564
|
setSearch("");
|
|
22473
22565
|
setSearchInput("");
|
|
22474
22566
|
setLoading(false);
|
|
22567
|
+
setLoadingMore(false);
|
|
22475
22568
|
return;
|
|
22476
22569
|
}
|
|
22477
22570
|
setError("");
|
|
@@ -22540,150 +22633,139 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
22540
22633
|
type: "button",
|
|
22541
22634
|
style: styles.button,
|
|
22542
22635
|
disabled: loading,
|
|
22543
|
-
onClick: () =>
|
|
22636
|
+
onClick: () => {
|
|
22637
|
+
setSearchInput("");
|
|
22638
|
+
load(account.token, 1, "");
|
|
22639
|
+
},
|
|
22544
22640
|
children: [(0, react_jsx_runtime.jsx)(Icon, {
|
|
22545
22641
|
name: "refresh",
|
|
22546
22642
|
size: 15
|
|
22547
|
-
}), "
|
|
22643
|
+
}), "重置"]
|
|
22644
|
+
}),
|
|
22645
|
+
notice !== "" && (0, react_jsx_runtime.jsx)("span", {
|
|
22646
|
+
role: "status",
|
|
22647
|
+
style: styles.toast,
|
|
22648
|
+
children: notice
|
|
22548
22649
|
})
|
|
22549
22650
|
]
|
|
22550
22651
|
}),
|
|
22551
22652
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
22653
|
+
ref: bodyRef,
|
|
22552
22654
|
style: styles.body,
|
|
22553
|
-
children: [
|
|
22554
|
-
|
|
22555
|
-
|
|
22556
|
-
(0, react_jsx_runtime.jsx)(Icon, {
|
|
22557
|
-
name: "folder",
|
|
22558
|
-
size: 30
|
|
22559
|
-
}),
|
|
22560
|
-
(0, react_jsx_runtime.jsx)("span", { children: "作品列表仅展示当前账号创建的内容" }),
|
|
22561
|
-
error !== "" && (0, react_jsx_runtime.jsx)("p", {
|
|
22562
|
-
style: styles.error,
|
|
22563
|
-
children: error
|
|
22564
|
-
}),
|
|
22565
|
-
(0, react_jsx_runtime.jsx)("button", {
|
|
22566
|
-
type: "button",
|
|
22567
|
-
style: {
|
|
22568
|
-
...styles.button,
|
|
22569
|
-
...styles.primary,
|
|
22570
|
-
...styles.loginButton
|
|
22571
|
-
},
|
|
22572
|
-
onClick: EdusLoginDialog.open,
|
|
22573
|
-
children: "立即登录"
|
|
22574
|
-
})
|
|
22575
|
-
]
|
|
22576
|
-
}) : loading ? (0, react_jsx_runtime.jsx)("div", {
|
|
22577
|
-
style: styles.center,
|
|
22578
|
-
children: "正在读取作品列表…"
|
|
22579
|
-
}) : list.length === 0 ? (0, react_jsx_runtime.jsx)("div", {
|
|
22580
|
-
style: styles.center,
|
|
22581
|
-
children: (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)(Icon, {
|
|
22582
|
-
name: "folder",
|
|
22583
|
-
size: 30
|
|
22584
|
-
}), (0, react_jsx_runtime.jsx)("p", { children: search === "" ? "还没有发布过作品" : "没有找到匹配的作品" })] })
|
|
22585
|
-
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
22586
|
-
style: styles.grid,
|
|
22587
|
-
children: list.map((work) => (0, react_jsx_runtime.jsxs)("article", {
|
|
22588
|
-
style: styles.card,
|
|
22655
|
+
children: [
|
|
22656
|
+
account === null ? (0, react_jsx_runtime.jsxs)("div", {
|
|
22657
|
+
style: styles.login,
|
|
22589
22658
|
children: [
|
|
22590
|
-
|
|
22591
|
-
|
|
22592
|
-
|
|
22593
|
-
style: styles.thumb
|
|
22594
|
-
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
22595
|
-
style: styles.placeholder,
|
|
22596
|
-
children: "暂无预览图"
|
|
22659
|
+
(0, react_jsx_runtime.jsx)(Icon, {
|
|
22660
|
+
name: "folder",
|
|
22661
|
+
size: 30
|
|
22597
22662
|
}),
|
|
22598
|
-
(0, react_jsx_runtime.
|
|
22599
|
-
|
|
22600
|
-
|
|
22601
|
-
|
|
22602
|
-
style: styles.cardTitle,
|
|
22603
|
-
children: work.title || "未命名作品"
|
|
22604
|
-
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
22605
|
-
style: styles.meta,
|
|
22606
|
-
children: [
|
|
22607
|
-
(0, react_jsx_runtime.jsx)("span", {
|
|
22608
|
-
style: styles.badge,
|
|
22609
|
-
children: statusOf(work.status)
|
|
22610
|
-
}),
|
|
22611
|
-
(0, react_jsx_runtime.jsx)("span", { children: formatDate(work.updatedAt) }),
|
|
22612
|
-
(0, react_jsx_runtime.jsxs)("span", {
|
|
22613
|
-
style: { marginLeft: "auto" },
|
|
22614
|
-
children: [work.views, " 次浏览"]
|
|
22615
|
-
})
|
|
22616
|
-
]
|
|
22617
|
-
})]
|
|
22663
|
+
(0, react_jsx_runtime.jsx)("span", { children: "作品列表仅展示当前账号创建的内容" }),
|
|
22664
|
+
error !== "" && (0, react_jsx_runtime.jsx)("p", {
|
|
22665
|
+
style: styles.error,
|
|
22666
|
+
children: error
|
|
22618
22667
|
}),
|
|
22619
|
-
(0, react_jsx_runtime.
|
|
22620
|
-
|
|
22621
|
-
|
|
22622
|
-
|
|
22623
|
-
|
|
22624
|
-
|
|
22625
|
-
|
|
22626
|
-
|
|
22627
|
-
|
|
22628
|
-
size: 14
|
|
22629
|
-
}), "打开"]
|
|
22630
|
-
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
22631
|
-
type: "button",
|
|
22632
|
-
style: {
|
|
22633
|
-
...styles.cardAction,
|
|
22634
|
-
borderRight: 0
|
|
22635
|
-
},
|
|
22636
|
-
disabled: sharing === work.id || work.status !== 2,
|
|
22637
|
-
onClick: () => void share(work, "copy"),
|
|
22638
|
-
children: [(0, react_jsx_runtime.jsx)(Icon, {
|
|
22639
|
-
name: "copy",
|
|
22640
|
-
size: 14
|
|
22641
|
-
}), sharing === work.id ? "处理中…" : "复制链接"]
|
|
22642
|
-
})]
|
|
22668
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
22669
|
+
type: "button",
|
|
22670
|
+
style: {
|
|
22671
|
+
...styles.button,
|
|
22672
|
+
...styles.primary,
|
|
22673
|
+
...styles.loginButton
|
|
22674
|
+
},
|
|
22675
|
+
onClick: EdusLoginDialog.open,
|
|
22676
|
+
children: "立即登录"
|
|
22643
22677
|
})
|
|
22644
22678
|
]
|
|
22645
|
-
},
|
|
22646
|
-
|
|
22647
|
-
|
|
22648
|
-
|
|
22649
|
-
|
|
22650
|
-
|
|
22651
|
-
|
|
22652
|
-
|
|
22653
|
-
|
|
22654
|
-
|
|
22655
|
-
|
|
22656
|
-
|
|
22657
|
-
|
|
22658
|
-
|
|
22659
|
-
|
|
22660
|
-
|
|
22661
|
-
|
|
22662
|
-
|
|
22663
|
-
|
|
22664
|
-
|
|
22665
|
-
|
|
22666
|
-
|
|
22667
|
-
|
|
22679
|
+
}) : loading ? (0, react_jsx_runtime.jsx)("div", {
|
|
22680
|
+
style: styles.center,
|
|
22681
|
+
children: "正在读取作品列表…"
|
|
22682
|
+
}) : list.length === 0 ? (0, react_jsx_runtime.jsx)("div", {
|
|
22683
|
+
style: styles.center,
|
|
22684
|
+
children: (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)(Icon, {
|
|
22685
|
+
name: "folder",
|
|
22686
|
+
size: 30
|
|
22687
|
+
}), (0, react_jsx_runtime.jsx)("p", { children: search === "" ? "还没有发布过作品" : "没有找到匹配的作品" })] })
|
|
22688
|
+
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
22689
|
+
style: styles.grid,
|
|
22690
|
+
children: list.map((work) => (0, react_jsx_runtime.jsxs)("article", {
|
|
22691
|
+
style: styles.card,
|
|
22692
|
+
children: [
|
|
22693
|
+
work.thumb ? (0, react_jsx_runtime.jsx)("img", {
|
|
22694
|
+
alt: "",
|
|
22695
|
+
src: work.thumb,
|
|
22696
|
+
style: styles.thumb
|
|
22697
|
+
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
22698
|
+
style: styles.placeholder,
|
|
22699
|
+
children: "暂无预览图"
|
|
22700
|
+
}),
|
|
22701
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
22702
|
+
style: styles.cardBody,
|
|
22703
|
+
children: [(0, react_jsx_runtime.jsx)("h3", {
|
|
22704
|
+
title: work.title,
|
|
22705
|
+
style: styles.cardTitle,
|
|
22706
|
+
children: work.title || "未命名作品"
|
|
22707
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
22708
|
+
style: styles.meta,
|
|
22709
|
+
children: [
|
|
22710
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
22711
|
+
style: styles.badge,
|
|
22712
|
+
children: statusOf(work.status)
|
|
22713
|
+
}),
|
|
22714
|
+
(0, react_jsx_runtime.jsx)("span", { children: formatDate(work.updatedAt) }),
|
|
22715
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
22716
|
+
style: { marginLeft: "auto" },
|
|
22717
|
+
children: [work.views, " 次浏览"]
|
|
22718
|
+
})
|
|
22719
|
+
]
|
|
22720
|
+
})]
|
|
22721
|
+
}),
|
|
22722
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
22723
|
+
style: styles.cardActions,
|
|
22724
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
22725
|
+
type: "button",
|
|
22726
|
+
style: styles.cardAction,
|
|
22727
|
+
disabled: sharing === work.id || work.status !== 2,
|
|
22728
|
+
onClick: () => void share(work, "open"),
|
|
22729
|
+
children: [(0, react_jsx_runtime.jsx)(Icon, {
|
|
22730
|
+
name: "open",
|
|
22731
|
+
size: 14
|
|
22732
|
+
}), "打开"]
|
|
22733
|
+
}), (0, react_jsx_runtime.jsxs)("button", {
|
|
22734
|
+
type: "button",
|
|
22735
|
+
style: {
|
|
22736
|
+
...styles.cardAction,
|
|
22737
|
+
borderRight: 0
|
|
22738
|
+
},
|
|
22739
|
+
disabled: sharing === work.id || work.status !== 2,
|
|
22740
|
+
onClick: () => void share(work, "copy"),
|
|
22741
|
+
children: [(0, react_jsx_runtime.jsx)(Icon, {
|
|
22742
|
+
name: "copy",
|
|
22743
|
+
size: 14
|
|
22744
|
+
}), sharing === work.id ? "处理中…" : "复制链接"]
|
|
22745
|
+
})]
|
|
22746
|
+
})
|
|
22747
|
+
]
|
|
22748
|
+
}, work.id))
|
|
22668
22749
|
}),
|
|
22669
|
-
(0, react_jsx_runtime.
|
|
22750
|
+
account !== null && error !== "" && (0, react_jsx_runtime.jsx)("p", {
|
|
22670
22751
|
style: {
|
|
22671
|
-
|
|
22672
|
-
|
|
22752
|
+
...styles.error,
|
|
22753
|
+
marginTop: 14
|
|
22673
22754
|
},
|
|
22674
|
-
children:
|
|
22675
|
-
|
|
22676
|
-
|
|
22677
|
-
|
|
22678
|
-
|
|
22679
|
-
|
|
22680
|
-
}), (0, react_jsx_runtime.jsx)("button", {
|
|
22755
|
+
children: error
|
|
22756
|
+
}),
|
|
22757
|
+
account !== null && !loading && list.length > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
22758
|
+
ref: sentinelRef,
|
|
22759
|
+
style: styles.more,
|
|
22760
|
+
children: loadingMore ? "正在加载更多…" : error !== "" && hasMore ? (0, react_jsx_runtime.jsx)("button", {
|
|
22681
22761
|
type: "button",
|
|
22682
22762
|
style: styles.button,
|
|
22683
|
-
|
|
22684
|
-
|
|
22685
|
-
|
|
22686
|
-
|
|
22763
|
+
onClick: () => {
|
|
22764
|
+
setError("");
|
|
22765
|
+
loadMore();
|
|
22766
|
+
},
|
|
22767
|
+
children: "重试加载"
|
|
22768
|
+
}) : hasMore ? "" : `已加载全部 ${list.length} 个作品`
|
|
22687
22769
|
})
|
|
22688
22770
|
]
|
|
22689
22771
|
})
|
|
@@ -22729,7 +22811,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
22729
22811
|
label: () => "教学网页",
|
|
22730
22812
|
description: () => "根据教学需求和配图,生成适合课堂投屏的网页",
|
|
22731
22813
|
icon: _deepseek_ai_dsh_client_ui_primitives.IconGlobeOutlineRegular,
|
|
22732
|
-
section: () => "任务"
|
|
22814
|
+
section: () => "任务",
|
|
22815
|
+
token: () => "教学网页"
|
|
22733
22816
|
}), "edus webpage command face");
|
|
22734
22817
|
});
|
|
22735
22818
|
}
|