Skip to content

Commit 5ebcd06

Browse files
Merge pull request #19 from christianhellsten/dark-mode
Dark mode
2 parents 30d9ae0 + e6bc5fb commit 5ebcd06

39 files changed

Lines changed: 354 additions & 137 deletions

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ollama-html-ui
22

3-
![cover](/screenshots/chat-collapsed.png)
3+
![cover](/videos/video.gif)
44

55
![Contributions Welcome](https://img.shields.io/badge/Contributions-welcome-blue.svg)
66

@@ -22,6 +22,13 @@ A HTML UI for [Ollama](https://ollama.ai).
2222
![Settings screen](/screenshots/settings.png)
2323
![Search](/screenshots/search.png)
2424

25+
**Dark mode**
26+
27+
![Chat (fullscreen)](/screenshots/darkmode-chat-collapsed.png)
28+
![Chat](/screenshots/darkmode-chat.png)
29+
![Settings screen](/screenshots/darkmode-settings.png)
30+
![Search](/screenshots/darkmode-search.png)
31+
2532
**Mobile**
2633

2734
![Chat (fullscreen)](/screenshots/mobile-chat-collapsed.png)
@@ -125,6 +132,9 @@ $ parcel build index.html
125132
- [ ] Image upload / multi-modal
126133
- [ ] Markdown support
127134
- [ ] Keyboard shortcuts
135+
- [ ] Dark & light theme
136+
- [ ] Vote up / down
137+
- [ ] Export chat messages to JSON
128138

129139
## Done
130140

css/ChatHistory.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Chat history */
22
#chat-history {
3-
mask-image: linear-gradient(180deg, $white 95%, transparent);
3+
mask-image: linear-gradient(180deg, var(--white) 95%, transparent);
44
display: flex;
55
flex-grow: 1;
66
flex-direction: column;
@@ -36,7 +36,7 @@
3636
/* Styling for system messages */
3737
.assistant-chat-message {
3838
.chat-message-text {
39-
color: #444;
39+
// color: var(--text-color-lighten-20);
4040
}
4141
margin-bottom: 0.5rem;
4242
}

css/ChatList.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
z-index: 2;
33
.chat-title {
44
// text-overflow: ellipsis;
5-
mask-image: linear-gradient(90deg, $white 95%, transparent); // Fade out title instead of ellipsis
5+
mask-image: linear-gradient(90deg, var(--white) 95%, transparent); // Fade out title instead of ellipsis
66
}
77
}
88

99
.list-item.selected {
10-
background: $white;
10+
background: var(--white);
1111
@extend %box-shadow;
1212
z-index: 2;
1313
}

css/DropDownMenu.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
}
44

55
.drop-down-menu-items {
6-
background: $bg-color;
6+
background: var(--bg-color);
77
position: absolute;
88
top: 100%; /* Position below the button */
99
display: none; /* Hide initially */

css/UINotification.scss

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
position: fixed;
33
top: 0;
44
left: 0;
5-
color: $bg-color;
6-
background-color: $text-color;
5+
color: var(--bg-color);
6+
background-color: var(--text-color);
77
width: calc(100vw - 2rem);
88
z-index: 30000;
9-
background-color: $bg-color;
9+
background-color: var(--bg-color);
1010
padding: 1rem;
1111
margin: 1rem;
1212
@extend %box-shadow-modal;
13-
border-radius: $border-radius;
13+
border-radius: var(--border-radius);
1414

1515
.button {
1616
border-radius: 2px;
@@ -23,5 +23,5 @@
2323
}
2424

2525
.notification-error {
26-
background: $error-color;
26+
background: var(--error-color);
2727
}

css/button.scss

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
button {
2-
background-color: $button-secondary-bgcolor;
2+
background-color: var(--button-secondary-bgcolor);
33
z-index: 1;
44
}
55

66
button {
77
padding: 0.75rem 1rem;
88
border: none;
9-
// border-radius: $border-radius;
9+
// border-radius: var(--border-radius);
1010
cursor: pointer;
1111

1212
i {
@@ -18,8 +18,8 @@ button {
1818
button:hover,
1919
button.selected {
2020
@extend %box-shadow-hover;
21-
//color: $button-primary-color;
22-
//background-color: $light-color;
21+
//color: var(--button-primary-color);
22+
//background-color: var(--light-color);
2323

2424
// @extend %box-shadow;
2525
}
@@ -37,13 +37,13 @@ button.selected {
3737
@extend %font-weight-boldest;
3838
@extend %box-shadow;
3939

40-
//color: $button-primary-color;
41-
//background-color: $button-primary-bgcolor;
40+
//color: var(--button-primary-color);
41+
//background-color: var(--button-primary-bgcolor);
4242
}
4343

4444
.button-primary:hover {
45-
//color: $button-primary-color;
46-
//background-color: $light-color;
45+
//color: var(--button-primary-color);
46+
//background-color: var(--light-color);
4747
}
4848

4949
.buttons {

css/colors.scss

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Light theme as default
2+
:root {
3+
--primary-color: #393E46;
4+
--secondary-color: #222831;
5+
--secondary-color-lighten-20: #{lighten(#222831, 20%)};
6+
--secondary-color-lighten-40: #{lighten(#222831, 40%)};
7+
--tertiary-color: #EEE;
8+
--error-color: #EF4040;
9+
--bg-color: #FAFAFA;
10+
--text-color: #333;
11+
--text-color-lighten-20: #{lighten(#eee, 20%)};
12+
--icon-color: var(--primary-color);
13+
--light-text-color: #FFFFFF;
14+
--button-primary-color: var(--primary-color);
15+
--button-primary-bgcolor: #FFFFFF;
16+
--button-secondary-color: var(--text-color);
17+
--button-secondary-bgcolor: $bg-color;
18+
--border-color: #{lighten(#393e46, 60%)};
19+
--border-hover-color: #{lighten(#393e46, 40%)};
20+
--border-focus-color: #{lighten(#393e46, 30%)};
21+
--box-shadow-color: rgba(196, 204, 213, 0.7490196078);
22+
--box-shadow-modal-color: #444;
23+
--modal-header-bg-color: var(--primary-color);
24+
}
25+
26+
// Dark theme for users who prefer dark mode
27+
@media (prefers-color-scheme: dark) {
28+
:root {
29+
--primary-color: #4f5b66;
30+
--secondary-color: #1c2025;
31+
--secondary-color-lighten-20: #{lighten(#1c2025, 20%)};
32+
--secondary-color-lighten-40: #{lighten(#1c2025, 40%)};
33+
--tertiary-color: #d1d1d1;
34+
--error-color: #ff6b6b;
35+
--bg-color: #121212;
36+
--text-color: #FAFAFA;
37+
--text-color-lighten-20: #{lighten(#FAFAFA, 20%)};
38+
--icon-color: var(--text-color);
39+
--light-text-color: #FFFFFF;
40+
--button-primary-color: #ffffff;
41+
--button-primary-bgcolor: var(--primary-color);
42+
--button-secondary-color: var(--text-color);
43+
--button-secondary-bgcolor: var(--bg-color);
44+
--border-color: #{lighten(#4f5b66, 30%)};
45+
--border-hover-color: #{lighten(#4f5b66, 50%)};
46+
--border-focus-color: #{lighten(#4f5b66, 60%)};
47+
--box-shadow-color: rgba(40, 48, 57, 0.7490196078);
48+
--box-shadow-modal-color: #444;
49+
--modal-header-bg-color: var(--bg-color);
50+
}
51+
}

css/form.scss

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,27 @@ textarea {
1010
width: 100%;
1111
padding: 0.5rem 0.75rem;
1212
display: inline-block;
13-
border: 1px solid $border-color;
13+
border: 1px solid var(--border-color);
1414
}
1515

1616
input.error,
1717
textarea.error {
18-
border: 1px solid $error-color !important;
18+
border: 1px solid var(--error-color) !important;
1919
}
2020

2121
input:focus,
2222
textarea:focus,
2323
[contenteditable]:focus {
24-
border: 1px solid $border-color;
25-
border-color: lighten($secondary-color, 40%);
24+
border: 1px solid var(--border-color);
25+
border-color: var(--secondary-color-lighten-40);
2626
outline: none !important;
2727

2828
@extend %box-shadow-hover;
2929
}
3030

3131
input:hover,
3232
textarea:hover {
33-
border: 1px solid lighten($secondary-color, 20%);
33+
border: 1px solid var(--secondary-color-lighten-40);
3434
}
3535

3636
.input {

css/icons.scss

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@
33
}
44

55
i[class^='icon-'] {
6-
color: $icon-color;
6+
color: var(--icon-color);
77
font-size: 12px;
88
vertical-align: middle;
99
}
1010

11+
svg {
12+
width: 24px;
13+
height: 24px;
14+
vertical-align: middle;
15+
}
16+
17+
.icon-close::before {
18+
content: '\00D7';
19+
}
20+
1121
.icon-download::before {
1222
content: '\1F4BE';
1323
}
@@ -55,8 +65,10 @@ i[class^='icon-'] {
5565
}
5666

5767
.icon-abort::before {
68+
content: '\00D7';
69+
color: var(--red);
5870
//content: "\00D7"; /* Unicode for ✖ */
59-
content: '\274C'; //
71+
// content: '\274C'; // ❌
6072
}
6173

6274
.icon-save::before {
@@ -91,6 +103,30 @@ i[class^='icon-'] {
91103
content: '\21A7';
92104
}
93105

106+
// Light theme
107+
:root {
108+
svg rect {
109+
fill: var(--text-color);
110+
stroke: var(--bg-color);
111+
}
112+
113+
.icon-settings rect {
114+
stroke: var(--text-color);
115+
fill: var(--bg-color);
116+
}
117+
}
118+
119+
// Dark theme
120+
@media (prefers-color-scheme: dark) {
121+
:root {
122+
svg rect {
123+
fill: var(--text-color);
124+
stroke: var(--bg-color);
125+
}
126+
}
127+
}
128+
129+
/*
94130
.icon-gpt {
95131
display: inline-block;
96132
width: 24px;
@@ -110,14 +146,15 @@ i[class^='icon-'] {
110146
111147
//background-image: url('data:image/svg+xml;base64,Cjxzdmcgd2lkdGg9IjUwIiBoZWlnaHQ9IjMwIiB2aWV3Qm94PSIwIDAgNTAgMzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPCEtLSBSb3VuZGVkIFJlY3RhbmdsZSBmb3IgdGhlIEJ1YmJsZSAtLT4KICA8cmVjdCB4PSIxIiB5PSIxIiB3aWR0aD0iNDgiIGhlaWdodD0iMjAiIHJ4PSIxMCIgcnk9IjEwIiBzdHJva2U9ImJsYWNrIiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlLXdpZHRoPSIyIi8+CgogIDwhLS0gVGFpbCBvZiB0aGUgU3BlZWNoIEJ1YmJsZSAtLT4KICA8cGF0aCBkPSJNIDIwLDIxIEwgMjUsMjUgTCAzMCwyMSBaIiBmaWxsPSJ0cmFuc3BhcmVudCIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIyIi8+Cjwvc3ZnPgo=');
112148
background-image: url('data:image/svg+xml;base64,Cjxzdmcgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgY2xhc3M9Imljb24tbWQiPgogIDxwb2x5Z29uIHBvaW50cz0iNC4yNSw0LjI1IDkuMjUsNC4yNSA2Ljc1LDkuMjUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiPjwvcG9seWdvbj4KICA8cG9seWdvbiBwb2ludHM9IjE0Ljc1LDQuMjUgMTkuNzUsNC4yNSAxNy4yNSw5LjI1IiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIj48L3BvbHlnb24+CiAgPHBvbHlnb24gcG9pbnRzPSI0LjI1LDE0Ljc1IDkuMjUsMTQuNzUgNi43NSwxOS43NSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSI+PC9wb2x5Z29uPgogIDxwb2x5Z29uIHBvaW50cz0iMTQuNzUsMTQuNzUgMTkuNzUsMTQuNzUgMTcuMjUsMTkuNzUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiPjwvcG9seWdvbj4KPC9zdmc+Cg==');
113-
width: 24px; /* Adjust as needed */
114-
height: 24px; /* Adjust as needed */
149+
width: 24px;
150+
height: 24px;
115151
}
116152
117153
.icon-hamburger {
118154
background-image: url('data:image/svg+xml;base64,Cjxzdmcgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDI0IDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDwhLS0gVG9wIFN0cmlwZSAtLT4KICA8cmVjdCB4PSI0IiB5PSI2IiB3aWR0aD0iMTYiIGhlaWdodD0iMiIgZmlsbD0iYmxhY2siPjwvcmVjdD4KCiAgPCEtLSBNaWRkbGUgU3RyaXBlIC0tPgogIDxyZWN0IHg9IjQiIHk9IjExIiB3aWR0aD0iMTYiIGhlaWdodD0iMiIgZmlsbD0iYmxhY2siPjwvcmVjdD4KCiAgPCEtLSBCb3R0b20gU3RyaXBlIC0tPgogIDxyZWN0IHg9IjQiIHk9IjE2IiB3aWR0aD0iMTYiIGhlaWdodD0iMiIgZmlsbD0iYmxhY2siPjwvcmVjdD4KPC9zdmc+Cg==');
119-
width: 24px; /* Adjust as needed */
120-
height: 24px; /* Adjust as needed */
155+
width: 24px;
156+
height: 24px;
121157
background-size: contain;
122158
background-repeat: no-repeat;
123159
}
160+
*/

css/list.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ ul {
3838
// NOTE: Should match #chat-header border-bottom
3939
border-top: 1px solid #cccccc5e;
4040

41-
//color: $button-primary-color;
42-
//background-color: $light-color;
41+
//color: var(--button-primary-color);
42+
//background-color: var(--light-color);
4343
//@extend %box-shadow;
4444
}
4545

0 commit comments

Comments
 (0)