add colors
This commit is contained in:
Vendored
+50
@@ -89,6 +89,56 @@ main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* src/colors.css */
|
||||||
|
[color]:not([color=standard]) {
|
||||||
|
--primary: hsl(var(--hue), 100%, 80%);
|
||||||
|
--gradient-luma-1: 70%;
|
||||||
|
--gradient-luma-2: 90%;
|
||||||
|
--hover-luma: 75%;
|
||||||
|
--active-luma: 80%;
|
||||||
|
--text-luma: 20%;
|
||||||
|
--surface:
|
||||||
|
linear-gradient(
|
||||||
|
|
||||||
|
120deg,
|
||||||
|
hsl(var(--hue), 100%, var(--gradient-luma-1)),
|
||||||
|
hsl(var(--hue), 100%, var(--gradient-luma-2)) );
|
||||||
|
--surface-hover: hsl(var(--hue), 100%, var(--hover-luma));
|
||||||
|
--surface-active: hsl(var(--hue), 100%, var(--active-luma));
|
||||||
|
--text-normal: hsl(var(--hue), 100%, var(--text-luma));
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
[color]:not([color=standard]) {
|
||||||
|
--gradient-luma-1: 20%;
|
||||||
|
--gradient-luma-2: 15%;
|
||||||
|
--hover-luma: 25%;
|
||||||
|
--active-luma: 30%;
|
||||||
|
--text-luma: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[color]:not([color=standard]).fill-color {
|
||||||
|
color: white;
|
||||||
|
background-color: var(--primary);
|
||||||
|
}
|
||||||
|
[color=coral] {
|
||||||
|
--hue: 20;
|
||||||
|
}
|
||||||
|
[color=yellow] {
|
||||||
|
--hue: 50;
|
||||||
|
}
|
||||||
|
[color=mint] {
|
||||||
|
--hue: 150;
|
||||||
|
}
|
||||||
|
[color=lightblue] {
|
||||||
|
--hue: 180;
|
||||||
|
}
|
||||||
|
[color=blue] {
|
||||||
|
--hue: 220;
|
||||||
|
}
|
||||||
|
[color=purple] {
|
||||||
|
--hue: 280;
|
||||||
|
}
|
||||||
|
|
||||||
/* src/View/chatPage.css */
|
/* src/View/chatPage.css */
|
||||||
#chat-page-wrapper {
|
#chat-page-wrapper {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
Vendored
+66
-2
@@ -353,11 +353,24 @@
|
|||||||
chats: [DATA_VERSION, "chat"],
|
chats: [DATA_VERSION, "chat"],
|
||||||
chatInfo: (id) => [DATA_VERSION, "chat", id, "info"],
|
chatInfo: (id) => [DATA_VERSION, "chat", id, "info"],
|
||||||
chatLastUsedPage: (id) => [DATA_VERSION, "chat", id, "last-used-page"],
|
chatLastUsedPage: (id) => [DATA_VERSION, "chat", id, "last-used-page"],
|
||||||
|
chatColor: (id) => [DATA_VERSION, "chat", id, "color"],
|
||||||
chatMessages: (id) => [DATA_VERSION, "chat", id, "messages"],
|
chatMessages: (id) => [DATA_VERSION, "chat", id, "messages"],
|
||||||
chatObjects: (id) => [DATA_VERSION, "chat", id, "objects"],
|
chatObjects: (id) => [DATA_VERSION, "chat", id, "objects"],
|
||||||
chatOutbox: (id) => [DATA_VERSION, "chat", id, "outbox"]
|
chatOutbox: (id) => [DATA_VERSION, "chat", id, "outbox"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// src/ViewModel/colors.ts
|
||||||
|
var Color = /* @__PURE__ */ ((Color2) => {
|
||||||
|
Color2["Standard"] = "standard";
|
||||||
|
Color2["Coral"] = "coral";
|
||||||
|
Color2["Yellow"] = "yellow";
|
||||||
|
Color2["Mint"] = "mint";
|
||||||
|
Color2["LightBlue"] = "lightblue";
|
||||||
|
Color2["Blue"] = "blue";
|
||||||
|
Color2["purple"] = "purple";
|
||||||
|
return Color2;
|
||||||
|
})(Color || {});
|
||||||
|
|
||||||
// src/Model/chatModel.ts
|
// src/Model/chatModel.ts
|
||||||
var ChatModel = class {
|
var ChatModel = class {
|
||||||
// data
|
// data
|
||||||
@@ -365,6 +378,7 @@
|
|||||||
storageModel;
|
storageModel;
|
||||||
chatListModel;
|
chatListModel;
|
||||||
info;
|
info;
|
||||||
|
color;
|
||||||
messages = /* @__PURE__ */ new Set();
|
messages = /* @__PURE__ */ new Set();
|
||||||
objects = /* @__PURE__ */ new Map();
|
objects = /* @__PURE__ */ new Map();
|
||||||
outbox = /* @__PURE__ */ new Set();
|
outbox = /* @__PURE__ */ new Set();
|
||||||
@@ -372,6 +386,9 @@
|
|||||||
get infoPath() {
|
get infoPath() {
|
||||||
return storageKeys.chatInfo(this.id);
|
return storageKeys.chatInfo(this.id);
|
||||||
}
|
}
|
||||||
|
get colorPath() {
|
||||||
|
return storageKeys.chatColor(this.id);
|
||||||
|
}
|
||||||
get messageDirPath() {
|
get messageDirPath() {
|
||||||
return storageKeys.chatMessages(this.id);
|
return storageKeys.chatMessages(this.id);
|
||||||
}
|
}
|
||||||
@@ -397,10 +414,17 @@
|
|||||||
this.info.secondaryChannels = secondaryChannels;
|
this.info.secondaryChannels = secondaryChannels;
|
||||||
this.storeInfo();
|
this.storeInfo();
|
||||||
};
|
};
|
||||||
|
setColor = (color) => {
|
||||||
|
this.color = color;
|
||||||
|
this.storeColor();
|
||||||
|
};
|
||||||
// store & add
|
// store & add
|
||||||
storeInfo = () => {
|
storeInfo = () => {
|
||||||
this.storageModel.storeStringifiable(this.infoPath, this.info);
|
this.storageModel.storeStringifiable(this.infoPath, this.info);
|
||||||
};
|
};
|
||||||
|
storeColor = () => {
|
||||||
|
this.storageModel.store(this.colorPath, this.color);
|
||||||
|
};
|
||||||
addMessage = (message) => {
|
addMessage = (message) => {
|
||||||
if (!this.messages.has(message)) {
|
if (!this.messages.has(message)) {
|
||||||
this.messages.add(message);
|
this.messages.add(message);
|
||||||
@@ -429,6 +453,15 @@
|
|||||||
this.info = generateChatInfo("0");
|
this.info = generateChatInfo("0");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
restoreColor = () => {
|
||||||
|
const path = this.colorPath;
|
||||||
|
const color = this.storageModel.restore(path);
|
||||||
|
if (!color) {
|
||||||
|
this.color = "standard" /* Standard */;
|
||||||
|
} else {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
};
|
||||||
restoreMessages = () => {
|
restoreMessages = () => {
|
||||||
const messageIds = this.storageModel.list(this.messageDirPath);
|
const messageIds = this.storageModel.list(this.messageDirPath);
|
||||||
if (!Array.isArray(messageIds)) return;
|
if (!Array.isArray(messageIds)) return;
|
||||||
@@ -465,6 +498,7 @@
|
|||||||
this.storageModel = storageModel2;
|
this.storageModel = storageModel2;
|
||||||
this.chatListModel = chatListModel;
|
this.chatListModel = chatListModel;
|
||||||
this.restoreInfo();
|
this.restoreInfo();
|
||||||
|
this.restoreColor();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
function generateChatInfo(primaryChannel) {
|
function generateChatInfo(primaryChannel) {
|
||||||
@@ -532,6 +566,7 @@
|
|||||||
index = new State(0);
|
index = new State(0);
|
||||||
primaryChannel = new State("");
|
primaryChannel = new State("");
|
||||||
primaryChannelInput = new State("");
|
primaryChannelInput = new State("");
|
||||||
|
color = new State("standard" /* Standard */);
|
||||||
selectedPage = new State(
|
selectedPage = new State(
|
||||||
"messages" /* Messages */
|
"messages" /* Messages */
|
||||||
);
|
);
|
||||||
@@ -557,6 +592,10 @@
|
|||||||
this.primaryChannel.value = this.chatModel.info.primaryChannel;
|
this.primaryChannel.value = this.chatModel.info.primaryChannel;
|
||||||
this.chatListViewModel.updateIndices();
|
this.chatListViewModel.updateIndices();
|
||||||
};
|
};
|
||||||
|
setColor = (newColor) => {
|
||||||
|
this.color.value = newColor;
|
||||||
|
this.chatModel.setColor(newColor);
|
||||||
|
};
|
||||||
// restore
|
// restore
|
||||||
restorePageSelection = () => {
|
restorePageSelection = () => {
|
||||||
const path = storageKeys.chatLastUsedPage(this.chatModel.id);
|
const path = storageKeys.chatLastUsedPage(this.chatModel.id);
|
||||||
@@ -575,6 +614,7 @@
|
|||||||
this.chatListViewModel = chatListViewModel2;
|
this.chatListViewModel = chatListViewModel2;
|
||||||
this.primaryChannel.value = chatModel.info.primaryChannel;
|
this.primaryChannel.value = chatModel.info.primaryChannel;
|
||||||
this.primaryChannelInput.value = chatModel.info.primaryChannel;
|
this.primaryChannelInput.value = chatModel.info.primaryChannel;
|
||||||
|
this.color.value = chatModel.color;
|
||||||
this.restorePageSelection();
|
this.restorePageSelection();
|
||||||
this.updateIndex();
|
this.updateIndex();
|
||||||
}
|
}
|
||||||
@@ -760,7 +800,31 @@
|
|||||||
},
|
},
|
||||||
translations.general.setButton,
|
translations.general.setButton,
|
||||||
/* @__PURE__ */ createElement("span", { class: "icon" }, "check")
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "check")
|
||||||
))));
|
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "flex-row gap width-input"
|
||||||
|
},
|
||||||
|
...Object.values(Color).map((color) => {
|
||||||
|
const isSelected = createProxyState(
|
||||||
|
[chatViewModel.color],
|
||||||
|
() => chatViewModel.color.value == color
|
||||||
|
);
|
||||||
|
function setColor() {
|
||||||
|
chatViewModel.setColor(color);
|
||||||
|
}
|
||||||
|
return /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
color,
|
||||||
|
class: "fill-color width-100 flex",
|
||||||
|
style: "height: 2rem",
|
||||||
|
"toggle:selected": isSelected,
|
||||||
|
"on:click": setColor
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/View/chatPage.tsx
|
// src/View/chatPage.tsx
|
||||||
@@ -1156,7 +1220,7 @@
|
|||||||
|
|
||||||
// src/View/Components/chatEntry.tsx
|
// src/View/Components/chatEntry.tsx
|
||||||
function ChatEntry(chatViewModel) {
|
function ChatEntry(chatViewModel) {
|
||||||
const view = /* @__PURE__ */ createElement("button", { class: "chat-entry tile", "on:click": chatViewModel.open }, /* @__PURE__ */ createElement(
|
const view = /* @__PURE__ */ createElement("button", { "set:color": chatViewModel.color, class: "chat-entry tile", "on:click": chatViewModel.open }, /* @__PURE__ */ createElement(
|
||||||
"span",
|
"span",
|
||||||
{
|
{
|
||||||
class: "shadow",
|
class: "shadow",
|
||||||
|
|||||||
Vendored
+25
-21
@@ -93,7 +93,11 @@ COLORS
|
|||||||
|
|
||||||
/* basic */
|
/* basic */
|
||||||
html {
|
html {
|
||||||
background-color: var(--background);
|
background: var(--background);
|
||||||
|
color: var(--text-normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tile {
|
||||||
color: var(--text-normal);
|
color: var(--text-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,12 +106,12 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal > div {
|
.modal > div {
|
||||||
background-color: var(--background);
|
background: var(--background);
|
||||||
}
|
}
|
||||||
|
|
||||||
menu,
|
menu,
|
||||||
header {
|
header {
|
||||||
background-color: var(--background-transparent);
|
background: var(--background-transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@@ -145,53 +149,53 @@ textarea:not(.tile *),
|
|||||||
select:not(.tile *),
|
select:not(.tile *),
|
||||||
.surface,
|
.surface,
|
||||||
.tile {
|
.tile {
|
||||||
background-color: var(--surface);
|
background: var(--surface);
|
||||||
}
|
}
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
button:hover,
|
button:hover,
|
||||||
select:hover,
|
select:hover,
|
||||||
button.tile.ghost:hover {
|
button.tile.ghost:hover {
|
||||||
background-color: var(--surface-hover);
|
background: var(--surface-hover);
|
||||||
}
|
}
|
||||||
[selected]:hover {
|
[selected]:hover {
|
||||||
background-color: var(--surface);
|
background: var(--surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button:active,
|
button:active,
|
||||||
select:active,
|
select:active,
|
||||||
button.tile.ghost:active,
|
button.tile.ghost:active,
|
||||||
[selected] {
|
[selected] {
|
||||||
background-color: var(--surface-active);
|
background: var(--surface-active);
|
||||||
}
|
}
|
||||||
[selected]:active {
|
[selected]:active {
|
||||||
background-color: var(--surface-hover);
|
background: var(--surface-hover);
|
||||||
}
|
}
|
||||||
.tile *,
|
.tile *,
|
||||||
header button {
|
header button {
|
||||||
background-color: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:checked {
|
input:checked {
|
||||||
background-color: var(--primary);
|
background: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* primary button */
|
/* primary button */
|
||||||
button.primary {
|
button.primary {
|
||||||
background-color: var(--primary);
|
background: var(--primary);
|
||||||
color: var(--text-on-color);
|
color: var(--text-on-color);
|
||||||
}
|
}
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
button.primary:hover {
|
button.primary:hover {
|
||||||
background-color: var(--primary-hover);
|
background: var(--primary-hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button.primary:active {
|
button.primary:active {
|
||||||
background-color: var(--primary-active);
|
background: var(--primary-active);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ghost button */
|
/* ghost button */
|
||||||
button.ghost:not(.tile) {
|
button.ghost:not(.tile) {
|
||||||
background-color: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
button.ghost {
|
button.ghost {
|
||||||
color: var(--link);
|
color: var(--link);
|
||||||
@@ -201,25 +205,25 @@ button.ghost {
|
|||||||
}
|
}
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
button.ghost:hover {
|
button.ghost:hover {
|
||||||
background-color: var(--background-hover);
|
background: var(--background-hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button.ghost:active {
|
button.ghost:active {
|
||||||
background-color: var(--background-active);
|
background: var(--background-active);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* danger button */
|
/* danger button */
|
||||||
button.danger {
|
button.danger {
|
||||||
background-color: var(--danger);
|
background: var(--danger);
|
||||||
color: var(--text-on-color);
|
color: var(--text-on-color);
|
||||||
}
|
}
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
button.danger:hover {
|
button.danger:hover {
|
||||||
background-color: var(--danger-hover);
|
background: var(--danger-hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
button.danger:active {
|
button.danger:active {
|
||||||
background-color: var(--danger-active);
|
background: var(--danger-active);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -909,7 +913,7 @@ input[type="checkbox"]:checked::before {
|
|||||||
input[type="radio"]:checked::before {
|
input[type="radio"]:checked::before {
|
||||||
content: "";
|
content: "";
|
||||||
|
|
||||||
background-color: var(--text-on-color);
|
background: var(--text-on-color);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
|
|
||||||
--inset: 4px;
|
--inset: 4px;
|
||||||
@@ -929,7 +933,7 @@ input[type="radio"]:checked::before {
|
|||||||
right: 0px;
|
right: 0px;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
|
|
||||||
background-color: var(--background);
|
background: var(--background);
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+34
-4
@@ -3,6 +3,7 @@
|
|||||||
import StorageModel, { storageKeys } from "./storageModel";
|
import StorageModel, { storageKeys } from "./storageModel";
|
||||||
|
|
||||||
import ChatListModel from "./chatListModel";
|
import ChatListModel from "./chatListModel";
|
||||||
|
import { Color } from "../ViewModel/colors";
|
||||||
import { checkIsValidObject } from "./Utility/typeSafety";
|
import { checkIsValidObject } from "./Utility/typeSafety";
|
||||||
import { createTimestamp } from "./Utility/utility";
|
import { createTimestamp } from "./Utility/utility";
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
@@ -13,6 +14,7 @@ export class ChatModel {
|
|||||||
storageModel: StorageModel;
|
storageModel: StorageModel;
|
||||||
chatListModel: ChatListModel;
|
chatListModel: ChatListModel;
|
||||||
info: ChatInfo;
|
info: ChatInfo;
|
||||||
|
color: Color;
|
||||||
|
|
||||||
messages = new Set<ChatMessage>();
|
messages = new Set<ChatMessage>();
|
||||||
objects = new Map<string, ChatObject>();
|
objects = new Map<string, ChatObject>();
|
||||||
@@ -23,6 +25,10 @@ export class ChatModel {
|
|||||||
return storageKeys.chatInfo(this.id);
|
return storageKeys.chatInfo(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get colorPath(): string[] {
|
||||||
|
return storageKeys.chatColor(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
get messageDirPath(): string[] {
|
get messageDirPath(): string[] {
|
||||||
return storageKeys.chatMessages(this.id);
|
return storageKeys.chatMessages(this.id);
|
||||||
}
|
}
|
||||||
@@ -55,11 +61,20 @@ export class ChatModel {
|
|||||||
this.storeInfo();
|
this.storeInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setColor = (color: Color): void => {
|
||||||
|
this.color = color;
|
||||||
|
this.storeColor();
|
||||||
|
};
|
||||||
|
|
||||||
// store & add
|
// store & add
|
||||||
storeInfo = (): void => {
|
storeInfo = (): void => {
|
||||||
this.storageModel.storeStringifiable(this.infoPath, this.info);
|
this.storageModel.storeStringifiable(this.infoPath, this.info);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
storeColor = (): void => {
|
||||||
|
this.storageModel.store(this.colorPath, this.color);
|
||||||
|
};
|
||||||
|
|
||||||
addMessage = (message: ChatMessage): void => {
|
addMessage = (message: ChatMessage): void => {
|
||||||
if (!this.messages.has(message)) {
|
if (!this.messages.has(message)) {
|
||||||
this.messages.add(message);
|
this.messages.add(message);
|
||||||
@@ -81,7 +96,7 @@ export class ChatModel {
|
|||||||
this.chatListModel.untrackChat(this);
|
this.chatListModel.untrackChat(this);
|
||||||
|
|
||||||
// delete
|
// delete
|
||||||
const dirPath = [...storageKeys.chats, this.id];
|
const dirPath: string[] = [...storageKeys.chats, this.id];
|
||||||
this.storageModel.removeRecursive(dirPath);
|
this.storageModel.removeRecursive(dirPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,9 +104,19 @@ export class ChatModel {
|
|||||||
restoreInfo = (): void => {
|
restoreInfo = (): void => {
|
||||||
const info: any = this.storageModel.restoreStringifiable(this.infoPath);
|
const info: any = this.storageModel.restoreStringifiable(this.infoPath);
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
this.info = info
|
this.info = info;
|
||||||
} else {
|
} else {
|
||||||
this.info = generateChatInfo("0")
|
this.info = generateChatInfo("0");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
restoreColor = (): void => {
|
||||||
|
const path: string[] = this.colorPath;
|
||||||
|
const color: string | null = this.storageModel.restore(path);
|
||||||
|
if (!color) {
|
||||||
|
this.color = Color.Standard;
|
||||||
|
} else {
|
||||||
|
this.color = color as any;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -135,12 +160,17 @@ export class ChatModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(storageModel: StorageModel, chatListModel: ChatListModel, chatId: string) {
|
constructor(
|
||||||
|
storageModel: StorageModel,
|
||||||
|
chatListModel: ChatListModel,
|
||||||
|
chatId: string
|
||||||
|
) {
|
||||||
this.id = chatId;
|
this.id = chatId;
|
||||||
this.storageModel = storageModel;
|
this.storageModel = storageModel;
|
||||||
this.chatListModel = chatListModel;
|
this.chatListModel = chatListModel;
|
||||||
|
|
||||||
this.restoreInfo();
|
this.restoreInfo();
|
||||||
|
this.restoreColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ export const storageKeys = {
|
|||||||
chats: [DATA_VERSION, "chat"],
|
chats: [DATA_VERSION, "chat"],
|
||||||
chatInfo: (id: string) => [DATA_VERSION, "chat", id, "info"],
|
chatInfo: (id: string) => [DATA_VERSION, "chat", id, "info"],
|
||||||
chatLastUsedPage: (id: string) => [DATA_VERSION, "chat", id, "last-used-page"],
|
chatLastUsedPage: (id: string) => [DATA_VERSION, "chat", id, "last-used-page"],
|
||||||
|
chatColor: (id: string) => [DATA_VERSION, "chat", id, "color"],
|
||||||
chatMessages: (id: string) => [DATA_VERSION, "chat", id, "messages"],
|
chatMessages: (id: string) => [DATA_VERSION, "chat", id, "messages"],
|
||||||
chatObjects: (id: string) => [DATA_VERSION, "chat", id, "objects"],
|
chatObjects: (id: string) => [DATA_VERSION, "chat", id, "objects"],
|
||||||
chatOutbox: (id: string) => [DATA_VERSION, "chat", id, "outbox"],
|
chatOutbox: (id: string) => [DATA_VERSION, "chat", id, "outbox"],
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ChatViewModel from "../../ViewModel/chatViewModel";
|
import ChatViewModel from "../../ViewModel/chatViewModel";
|
||||||
|
import { Color } from "../../ViewModel/colors";
|
||||||
import { translations } from "../translations";
|
import { translations } from "../translations";
|
||||||
|
|
||||||
export function SettingsPage(chatViewModel: ChatViewModel) {
|
export function SettingsPage(chatViewModel: ChatViewModel) {
|
||||||
@@ -32,6 +33,33 @@ export function SettingsPage(chatViewModel: ChatViewModel) {
|
|||||||
<span class="icon">check</span>
|
<span class="icon">check</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr></hr>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex-row gap width-input"
|
||||||
|
>
|
||||||
|
{...Object.values(Color).map((color) => {
|
||||||
|
const isSelected = React.createProxyState(
|
||||||
|
[chatViewModel.color],
|
||||||
|
() => chatViewModel.color.value == color
|
||||||
|
);
|
||||||
|
|
||||||
|
function setColor() {
|
||||||
|
chatViewModel.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
color={color}
|
||||||
|
class="fill-color width-100 flex"
|
||||||
|
style="height: 2rem"
|
||||||
|
toggle:selected={isSelected}
|
||||||
|
on:click={setColor}
|
||||||
|
></button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import ChatViewModel from "../../ViewModel/chatViewModel";
|
|||||||
|
|
||||||
export function ChatEntry(chatViewModel: ChatViewModel) {
|
export function ChatEntry(chatViewModel: ChatViewModel) {
|
||||||
const view = (
|
const view = (
|
||||||
<button class="chat-entry tile" on:click={chatViewModel.open}>
|
<button set:color={chatViewModel.color} class="chat-entry tile" on:click={chatViewModel.open}>
|
||||||
<span
|
<span
|
||||||
class="shadow"
|
class="shadow"
|
||||||
subscribe:innerText={chatViewModel.primaryChannel}
|
subscribe:innerText={chatViewModel.primaryChannel}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import StorageModel, { storageKeys } from "../Model/storageModel";
|
|||||||
|
|
||||||
import ChatListViewModel from "./chatListViewModel";
|
import ChatListViewModel from "./chatListViewModel";
|
||||||
import { ChatModel } from "../Model/chatModel";
|
import { ChatModel } from "../Model/chatModel";
|
||||||
|
import { Color } from "./colors";
|
||||||
|
|
||||||
export default class ChatViewModel {
|
export default class ChatViewModel {
|
||||||
chatModel: ChatModel;
|
chatModel: ChatModel;
|
||||||
@@ -16,6 +17,8 @@ export default class ChatViewModel {
|
|||||||
primaryChannel: React.State<string> = new React.State("");
|
primaryChannel: React.State<string> = new React.State("");
|
||||||
primaryChannelInput: React.State<string> = new React.State("");
|
primaryChannelInput: React.State<string> = new React.State("");
|
||||||
|
|
||||||
|
color: React.State<Color> = new React.State<Color>(Color.Standard);
|
||||||
|
|
||||||
selectedPage: React.State<ChatPageType> = new React.State<ChatPageType>(
|
selectedPage: React.State<ChatPageType> = new React.State<ChatPageType>(
|
||||||
ChatPageType.Messages
|
ChatPageType.Messages
|
||||||
);
|
);
|
||||||
@@ -49,6 +52,11 @@ export default class ChatViewModel {
|
|||||||
this.chatListViewModel.updateIndices();
|
this.chatListViewModel.updateIndices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setColor = (newColor: Color): void => {
|
||||||
|
this.color.value = newColor;
|
||||||
|
this.chatModel.setColor(newColor);
|
||||||
|
}
|
||||||
|
|
||||||
// restore
|
// restore
|
||||||
restorePageSelection = (): void => {
|
restorePageSelection = (): void => {
|
||||||
const path: string[] = storageKeys.chatLastUsedPage(this.chatModel.id);
|
const path: string[] = storageKeys.chatLastUsedPage(this.chatModel.id);
|
||||||
@@ -71,6 +79,8 @@ export default class ChatViewModel {
|
|||||||
this.primaryChannel.value = chatModel.info.primaryChannel;
|
this.primaryChannel.value = chatModel.info.primaryChannel;
|
||||||
this.primaryChannelInput.value = chatModel.info.primaryChannel;
|
this.primaryChannelInput.value = chatModel.info.primaryChannel;
|
||||||
|
|
||||||
|
this.color.value = chatModel.color;
|
||||||
|
|
||||||
this.restorePageSelection();
|
this.restorePageSelection();
|
||||||
this.updateIndex();
|
this.updateIndex();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export enum Color {
|
||||||
|
Standard = "standard",
|
||||||
|
Coral = "coral",
|
||||||
|
Yellow = "yellow",
|
||||||
|
Mint = "mint",
|
||||||
|
LightBlue = "lightblue",
|
||||||
|
Blue = "blue",
|
||||||
|
purple = "purple",
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
[color]:not([color="standard"]) {
|
||||||
|
--primary: hsl(var(--hue), 100%, 80%);
|
||||||
|
|
||||||
|
--gradient-luma-1: 70%;
|
||||||
|
--gradient-luma-2: 90%;
|
||||||
|
|
||||||
|
--hover-luma: 75%;
|
||||||
|
--active-luma: 80%;
|
||||||
|
|
||||||
|
--text-luma: 20%;
|
||||||
|
|
||||||
|
--surface: linear-gradient(
|
||||||
|
120deg,
|
||||||
|
hsl(var(--hue), 100%, var(--gradient-luma-1)),
|
||||||
|
hsl(var(--hue), 100%, var(--gradient-luma-2))
|
||||||
|
);
|
||||||
|
--surface-hover: hsl(var(--hue), 100%, var(--hover-luma));
|
||||||
|
--surface-active: hsl(var(--hue), 100%, var(--active-luma));
|
||||||
|
|
||||||
|
--text-normal: hsl(var(--hue), 100%, var(--text-luma));
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
[color]:not([color="standard"]) {
|
||||||
|
--gradient-luma-1: 20%;
|
||||||
|
--gradient-luma-2: 15%;
|
||||||
|
|
||||||
|
--hover-luma: 25%;
|
||||||
|
--active-luma: 30%;
|
||||||
|
|
||||||
|
--text-luma: 90%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[color]:not([color="standard"]).fill-color {
|
||||||
|
color: white;
|
||||||
|
background-color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
[color="coral"] {
|
||||||
|
--hue: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
[color="yellow"] {
|
||||||
|
--hue: 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
[color="mint"] {
|
||||||
|
--hue: 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
[color="lightblue"] {
|
||||||
|
--hue: 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
[color="blue"] {
|
||||||
|
--hue: 220;
|
||||||
|
}
|
||||||
|
|
||||||
|
[color="purple"] {
|
||||||
|
--hue: 280;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import "./base.css";
|
import "./base.css";
|
||||||
|
import "./colors.css";
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user