Skip to content

Commit 4fb9247

Browse files
author
Working On It
committed
feat: support Theme button(casibase#1356)
1 parent 5b98ee2 commit 4fb9247

22 files changed

+192
-57
lines changed

conf/app.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ staticBaseUrl = "https://cdn.casibase.org"
3737
htmlTitle = "Casibase"
3838
faviconUrl = "https://cdn.casibase.com/static/favicon.png"
3939
logoUrl = "https://cdn.casibase.org/img/casibase-logo_1200x256.png"
40+
logoWhiteUrl = "https://cdn.casibase.org/img/casibase-logo_1200x256_white.png"
4041
navbarHtml = ""
4142
footerHtml = "Powered by <a target="_blank" href="https://github.com/casibase/casibase" rel="noreferrer"><img style="padding-bottom: 3px;" height="20" alt="Casibase" src="https://cdn.casibase.org/img/casibase-logo_1200x256.png" /></a>"
4243
appUrl = ""

conf/conf.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type WebConfig struct {
4242
HtmlTitle string `json:"htmlTitle"`
4343
FaviconUrl string `json:"faviconUrl"`
4444
LogoUrl string `json:"logoUrl"`
45+
LogoWhiteUrl string `json:"logoWhiteUrl"`
4546
NavbarHtml string `json:"navbarHtml"`
4647
FooterHtml string `json:"footerHtml"`
4748
AppUrl string `json:"appUrl"`
@@ -219,6 +220,7 @@ func GetWebConfig() *WebConfig {
219220
config.HtmlTitle = GetConfigString("htmlTitle")
220221
config.FaviconUrl = GetConfigString("faviconUrl")
221222
config.LogoUrl = GetConfigString("logoUrl")
223+
config.LogoWhiteUrl = GetConfigString("logoWhiteUrl")
222224
config.NavbarHtml = GetConfigString("navbarHtml")
223225
config.FooterHtml = GetConfigString("footerHtml")
224226
config.AppUrl = GetConfigString("appUrl")

web/src/App.js

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import SigninPage from "./SigninPage";
3939
import i18next from "i18next";
4040
import {withTranslation} from "react-i18next";
4141
import LanguageSelect from "./LanguageSelect";
42+
import ThemeSelect from "./ThemeSelect";
4243
import ChatEditPage from "./ChatEditPage";
4344
import ChatListPage from "./ChatListPage";
4445
import MessageListPage from "./MessageListPage";
@@ -86,12 +87,21 @@ const {Header, Footer, Content} = Layout;
8687
class App extends Component {
8788
constructor(props) {
8889
super(props);
90+
this.setThemeAlgorithm();
91+
let storageThemeAlgorithm = [];
92+
try {
93+
storageThemeAlgorithm = localStorage.getItem("themeAlgorithm") ? JSON.parse(localStorage.getItem("themeAlgorithm")) : ["default"];
94+
} catch {
95+
storageThemeAlgorithm = ["default"];
96+
}
8997
this.state = {
9098
classes: props,
9199
selectedMenuKey: 0,
92100
account: undefined,
93101
uri: null,
102+
themeAlgorithm: storageThemeAlgorithm,
94103
themeData: Conf.ThemeDefault,
104+
logo: this.getLogo(storageThemeAlgorithm),
95105
menuVisible: false,
96106
forms: [],
97107
};
@@ -304,6 +314,27 @@ class App extends Component {
304314
});
305315
};
306316

317+
setThemeAlgorithm() {
318+
const currentUrl = window.location.href;
319+
const url = new URL(currentUrl);
320+
const themeType = url.searchParams.get("theme");
321+
if (themeType === "dark" || themeType === "default") {
322+
localStorage.setItem("themeAlgorithm", JSON.stringify([themeType]));
323+
}
324+
}
325+
326+
setLogoAndThemeAlgorithm = (nextThemeAlgorithm) => {
327+
this.setState({
328+
themeAlgorithm: nextThemeAlgorithm,
329+
logo: this.getLogo(nextThemeAlgorithm),
330+
});
331+
localStorage.setItem("themeAlgorithm", JSON.stringify(nextThemeAlgorithm));
332+
};
333+
334+
getLogo(themes) {
335+
return Setting.getLogo(themes);
336+
}
337+
307338
renderAvatar() {
308339
if (this.state.account.avatar === "") {
309340
return (
@@ -399,6 +430,9 @@ class App extends Component {
399430
{i18next.t("account:Sign In")}
400431
</a>
401432
</div>
433+
<div style={{float: "right", margin: "0px", padding: "0px"}}>
434+
<ThemeSelect themeAlgorithm={this.state.themeAlgorithm} onChange={this.setLogoAndThemeAlgorithm} />
435+
</div>
402436
<div style={{float: "right", margin: "0px", padding: "0px"}}>
403437
<LanguageSelect />
404438
</div>
@@ -408,6 +442,7 @@ class App extends Component {
408442
return (
409443
<React.Fragment>
410444
{this.renderRightDropdown()}
445+
<ThemeSelect themeAlgorithm={this.state.themeAlgorithm} onChange={this.setLogoAndThemeAlgorithm} />
411446
<LanguageSelect />
412447
<div style={{float: "right", marginRight: "20px", padding: "0px"}}>
413448
<div dangerouslySetInnerHTML={{__html: Conf.NavbarHtml}} />
@@ -515,7 +550,7 @@ class App extends Component {
515550
Setting.goToLinkSoft(this, "/videos");
516551
}
517552
} else {
518-
const textColor = "black";
553+
const textColor = this.state.themeAlgorithm.includes("dark") ? "white" : "black";
519554
const twoToneColor = this.state.themeData.colorPrimary;
520555

521556
res.pop();
@@ -635,23 +670,23 @@ class App extends Component {
635670
<Route exact path="/access/:owner/:name" render={(props) => this.renderSigninIfNotSignedIn(<AccessPage account={this.state.account} {...props} />)} />
636671
<Route exact path="/callback" component={AuthCallback} />
637672
<Route exact path="/signin" render={(props) => this.renderHomeIfSignedIn(<SigninPage {...props} />)} />
638-
<Route exact path="/" render={(props) => this.renderSigninIfNotSignedIn(<HomePage account={this.state.account} {...props} />)} />
639-
<Route exact path="/home" render={(props) => this.renderSigninIfNotSignedIn(<HomePage account={this.state.account} {...props} />)} />
673+
<Route exact path="/" render={(props) => this.renderSigninIfNotSignedIn(<HomePage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
674+
<Route exact path="/home" render={(props) => this.renderSigninIfNotSignedIn(<HomePage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
640675
<Route exact path="/stores" render={(props) => this.renderSigninIfNotSignedIn(<StoreListPage account={this.state.account} {...props} />)} />
641676
<Route exact path="/stores/:owner/:storeName" render={(props) => this.renderSigninIfNotSignedIn(<StoreEditPage account={this.state.account} {...props} />)} />
642677
<Route exact path="/stores/:owner/:storeName/view" render={(props) => this.renderSigninIfNotSignedIn(<FileTreePage account={this.state.account} {...props} />)} />
643-
<Route exact path="/stores/:owner/:storeName/chats" render={(props) => this.renderSigninIfNotSignedIn(<ChatListPage account={this.state.account} {...props} />)} />
678+
<Route exact path="/stores/:owner/:storeName/chats" render={(props) => this.renderSigninIfNotSignedIn(<ChatListPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
644679
<Route exact path="/stores/:owner/:storeName/messages" render={(props) => this.renderSigninIfNotSignedIn(<MessageListPage account={this.state.account} {...props} />)} />
645680
<Route exact path="/videos" render={(props) => this.renderSigninIfNotSignedIn(<VideoListPage account={this.state.account} {...props} />)} />
646-
<Route exact path="/videos/:owner/:videoName" render={(props) => this.renderSigninIfNotSignedIn(<VideoEditPage account={this.state.account} {...props} />)} />
681+
<Route exact path="/videos/:owner/:videoName" render={(props) => this.renderSigninIfNotSignedIn(<VideoEditPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
647682
<Route exact path="/public-videos" render={(props) => <PublicVideoListPage {...props} />} />
648683
<Route exact path="/public-videos/:owner/:videoName" render={(props) => <VideoPage account={this.state.account} {...props} />} />
649684
<Route exact path="/providers" render={(props) => this.renderSigninIfNotSignedIn(<ProviderListPage account={this.state.account} {...props} />)} />
650-
<Route exact path="/providers/:providerName" render={(props) => this.renderSigninIfNotSignedIn(<ProviderEditPage account={this.state.account} {...props} />)} />
685+
<Route exact path="/providers/:providerName" render={(props) => this.renderSigninIfNotSignedIn(<ProviderEditPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
651686
<Route exact path="/vectors" render={(props) => this.renderSigninIfNotSignedIn(<VectorListPage account={this.state.account} {...props} />)} />
652687
<Route exact path="/vectors/:vectorName" render={(props) => this.renderSigninIfNotSignedIn(<VectorEditPage account={this.state.account} {...props} />)} />
653-
<Route exact path="/chats" render={(props) => this.renderSigninIfNotSignedIn(<ChatListPage account={this.state.account} {...props} />)} />
654-
<Route exact path="/chats/:chatName" render={(props) => this.renderSigninIfNotSignedIn(<ChatEditPage account={this.state.account} {...props} />)} />
688+
<Route exact path="/chats" render={(props) => this.renderSigninIfNotSignedIn(<ChatListPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
689+
<Route exact path="/chats/:chatName" render={(props) => this.renderSigninIfNotSignedIn(<ChatEditPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
655690
<Route exact path="/messages" render={(props) => this.renderSigninIfNotSignedIn(<MessageListPage account={this.state.account} {...props} />)} />
656691
<Route exact path="/messages/:messageName" render={(props) => this.renderSigninIfNotSignedIn(<MessageEditPage account={this.state.account} {...props} />)} />
657692
<Route exact path="/usages" render={(props) => this.renderSigninIfNotSignedIn(<UsagePage account={this.state.account} {...props} />)} />
@@ -676,17 +711,17 @@ class App extends Component {
676711
<Route exact path="/yolov8mi" render={(props) => this.renderSigninIfNotSignedIn(<PythonYolov8miPage account={this.state.account} {...props} />)} />
677712
<Route exact path="/sr" render={(props) => this.renderSigninIfNotSignedIn(<PythonSrPage account={this.state.account} {...props} />)} />
678713
<Route exact path="/tasks" render={(props) => this.renderSigninIfNotSignedIn(<TaskListPage account={this.state.account} {...props} />)} />
679-
<Route exact path="/tasks/:taskName" render={(props) => this.renderSigninIfNotSignedIn(<TaskEditPage account={this.state.account} {...props} />)} />
714+
<Route exact path="/tasks/:taskName" render={(props) => this.renderSigninIfNotSignedIn(<TaskEditPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
680715
<Route exact path="/forms" render={(props) => this.renderSigninIfNotSignedIn(<FormListPage account={this.state.account} {...props} />)} />
681716
<Route exact path="/forms/:formName" render={(props) => this.renderSigninIfNotSignedIn(<FormEditPage account={this.state.account} {...props} />)} />
682717
<Route exact path="/forms/:formName/data" render={(props) => this.renderSigninIfNotSignedIn(<FormDataPage key={props.match.params.formName} account={this.state.account} {...props} />)} />
683718
<Route exact path="/articles" render={(props) => this.renderSigninIfNotSignedIn(<ArticleListPage account={this.state.account} {...props} />)} />
684719
<Route exact path="/articles/:articleName" render={(props) => this.renderSigninIfNotSignedIn(<ArticleEditPage account={this.state.account} {...props} />)} />
685-
<Route exact path="/chat" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} />)} />
686-
<Route exact path="/chat/:chatName" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} />)} />
687-
<Route exact path="/stores/:owner/:storeName/chat" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} />)} />
688-
<Route exact path="/:owner/:storeName/chat" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} />)} />
689-
<Route exact path="/:owner/:storeName/chat/:chatName" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} />)} />
720+
<Route exact path="/chat" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
721+
<Route exact path="/chat/:chatName" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
722+
<Route exact path="/stores/:owner/:storeName/chat" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
723+
<Route exact path="/:owner/:storeName/chat" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
724+
<Route exact path="/:owner/:storeName/chat/:chatName" render={(props) => this.renderSigninIfNotSignedIn(<ChatPage account={this.state.account} {...props} themeAlgorithm={this.state.themeAlgorithm} />)} />
690725
<Route exact path="/workbench" render={(props) => this.renderSigninIfNotSignedIn(<NodeWorkbench account={this.state.account} {...props} />)} />
691726
<Route exact path="/sysinfo" render={(props) => this.renderSigninIfNotSignedIn(<SystemInfo account={this.state.account} {...props} />)} />
692727
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")} extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
@@ -713,7 +748,7 @@ class App extends Component {
713748
renderContent() {
714749
if (Setting.getUrlParam("isRaw") !== null) {
715750
return (
716-
<HomePage account={this.state.account} />
751+
<HomePage account={this.state.account} themeAlgorithm={this.state.themeAlgorithm} />
717752
);
718753
} else if (Setting.getSubdomain() === "portal") {
719754
return (
@@ -762,11 +797,11 @@ class App extends Component {
762797
};
763798

764799
return (
765-
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: "white", display: "flex", justifyContent: "space-between"}}>
800+
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: this.state.themeAlgorithm.includes("dark") ? "black" : "white", display: "flex", justifyContent: "space-between"}}>
766801
<div style={{display: "flex", alignItems: "center", flex: 1, overflow: "hidden"}}>
767802
{Setting.isMobile() ? null : (
768803
<Link to={"/"}>
769-
<img className="logo" src={Conf.LogoUrl} alt="logo" />
804+
<img className="logo" src={this.state.themeAlgorithm.includes("dark") ? Conf.LogoWhiteUrl : Conf.LogoUrl} alt="logo" />
770805
</Link>
771806
)}
772807
{Setting.isMobile() ? (
@@ -809,8 +844,6 @@ class App extends Component {
809844
<React.Fragment>
810845
<Footer id="footer" style={
811846
{
812-
borderTop: "1px solid #e8e8e8",
813-
backgroundColor: "white",
814847
textAlign: "center",
815848
height: "67px",
816849
}
@@ -849,7 +882,7 @@ class App extends Component {
849882
colorInfo: this.state.themeData.colorPrimary,
850883
borderRadius: this.state.themeData.borderRadius,
851884
},
852-
// algorithm: Setting.getAlgorithm(this.state.themeAlgorithm),
885+
algorithm: Setting.getAlgorithm(this.state.themeAlgorithm),
853886
}}>
854887
<StyleProvider hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
855888
{

web/src/App.less

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ img {
3333
flex-direction: column;
3434
height: 100%;
3535
min-height: 100vh;
36-
background-color: white;
3736
}
3837

3938
.content-warp-card {
@@ -66,10 +65,6 @@ img {
6665
height: 65px;
6766
float: right;
6867
cursor: pointer;
69-
70-
&:hover {
71-
background-color: #f5f5f5;
72-
}
7368
}
7469

7570
.select-box {
@@ -81,10 +76,6 @@ img {
8176
height: 64px;
8277
float: right;
8378
cursor: pointer;
84-
85-
&:hover {
86-
background-color: #f5f5f5 !important;
87-
}
8879
}
8980

9081
.rightDropDown {
@@ -95,11 +86,6 @@ img {
9586
float: right;
9687
cursor: pointer;
9788
margin-right: 3px;
98-
99-
&:hover {
100-
background-color: #f5f5f5;
101-
color: black;
102-
}
10389
}
10490

10591
.cs-conversation-header__content .cs-conversation-header__user-name {

web/src/ArticleEditPage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ class ArticleEditPage extends React.Component {
407407
{/* </Col>*/}
408408
<Col span={5} >
409409
<Affix offsetTop={0} style={{marginRight: "10px"}}>
410-
<div style={{backgroundColor: "white", height: "100vh", overflowY: "auto", borderRight: 0}}>
410+
<div style={{height: "100vh", overflowY: "auto", borderRight: 0}}>
411411
<ArticleMenu table={blocks} onGoToRow={(table, i) => {
412412
if (this.articleTableRef.current) {
413413
this.articleTableRef.current.goToRow(table, i);

web/src/ChatBox.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ class ChatBox extends React.Component {
368368
onVoiceInputStart={this.startVoiceInput}
369369
onVoiceInputEnd={this.stopVoiceInput}
370370
isVoiceInput={this.state.isVoiceInput}
371+
themeAlgorithm={this.props.themeAlgorithm}
371372
/>
372373
)}
373374
</Card>

web/src/ChatEditPage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ class ChatEditPage extends React.Component {
217217
</Col>
218218
<Col span={22} >
219219
<div style={{width: "50%", height: "800px"}}>
220-
<ChatBox disableInput={true} hideInput={true} messages={this.state.messages} sendMessage={null} account={this.props.account} />
220+
<ChatBox disableInput={true} hideInput={true} messages={this.state.messages} sendMessage={null} account={this.props.account} themeAlgorithm={this.props.themeAlgorithm} />
221221
</div>
222222
</Col>
223223
</Row>

web/src/ChatListPage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ class ChatListPage extends BaseListPage {
377377
overflowY: "auto",
378378
width: "100%",
379379
}}>
380-
<ChatBox disableInput={true} hideInput={true} messages={messages} sendMessage={null} account={this.props.account} previewMode={true} />
380+
<ChatBox disableInput={true} hideInput={true} messages={messages} sendMessage={null} account={this.props.account} previewMode={true} themeAlgorithm={this.props.themeAlgorithm} />
381381
</div>
382382
</div>
383383

0 commit comments

Comments
 (0)