clean model (A)
This commit is contained in:
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
trailingComma: "all"
|
||||||
|
tabWidth: 4
|
||||||
|
semi: true
|
||||||
|
singleQuote: false
|
||||||
|
plugins:
|
||||||
|
- "prettier-plugin-sort-imports"
|
||||||
|
sortingMethod: "alphabetical"
|
||||||
|
sortingOrder: "ascending"
|
||||||
|
stripNewlines: true
|
||||||
Vendored
+304
-304
@@ -1,78 +1,3 @@
|
|||||||
/* src/base.css */
|
|
||||||
#home-page,
|
|
||||||
#home-page #chat-section,
|
|
||||||
#chat-page,
|
|
||||||
#chat-page #main > div {
|
|
||||||
animation: slide-up var(--animation-duration) ease;
|
|
||||||
}
|
|
||||||
#background-wrapper {
|
|
||||||
position: fixed;
|
|
||||||
top: 0px;
|
|
||||||
left: var(--safe-area-left);
|
|
||||||
right: var(--safe-area-right);
|
|
||||||
bottom: 0px;
|
|
||||||
z-index: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
overflow: hidden;
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
#background-wrapper div {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: -80px;
|
|
||||||
left: -80px;
|
|
||||||
right: -80px;
|
|
||||||
bottom: -80px;
|
|
||||||
z-index: -1;
|
|
||||||
pointer-events: none;
|
|
||||||
filter: blur(40px);
|
|
||||||
}
|
|
||||||
#background-wrapper #sky {
|
|
||||||
left: -100%;
|
|
||||||
bottom: -50%;
|
|
||||||
--color-1: hsl(188, 100%, 83%);
|
|
||||||
--color-2: hsl(194, 72%, 56%);
|
|
||||||
background-image: radial-gradient(var(--color-1), var(--color-2));
|
|
||||||
}
|
|
||||||
#background-wrapper #grass-1 {
|
|
||||||
--color-1: hsl(150, 100%, 30%);
|
|
||||||
--color-2: hsl(150, 100%, 25%);
|
|
||||||
background-image:
|
|
||||||
linear-gradient(
|
|
||||||
350deg,
|
|
||||||
var(--color-1),
|
|
||||||
var(--color-2) 30%,
|
|
||||||
transparent 40%);
|
|
||||||
}
|
|
||||||
#background-wrapper #grass-2 {
|
|
||||||
--color-1: hsl(110, 100%, 40%);
|
|
||||||
--color-2: hsl(110, 100%, 35%);
|
|
||||||
background-image:
|
|
||||||
linear-gradient(
|
|
||||||
9deg,
|
|
||||||
var(--color-1),
|
|
||||||
var(--color-2) 30%,
|
|
||||||
transparent 35%);
|
|
||||||
}
|
|
||||||
body[theme=dark] #background-wrapper {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
body[theme=dark] #background-wrapper #sky {
|
|
||||||
--color-1: hsl(188, 100%, 30%);
|
|
||||||
--color-2: hsl(194, 72%, 24%);
|
|
||||||
}
|
|
||||||
body[theme=dark] #background-wrapper #grass-1 {
|
|
||||||
--color-1: hsl(120, 30%, 30%);
|
|
||||||
--color-2: hsl(120, 30%, 24%);
|
|
||||||
}
|
|
||||||
body[theme=dark] #background-wrapper #grass-2 {
|
|
||||||
--color-1: hsl(110, 60%, 30%);
|
|
||||||
--color-2: hsl(110, 50%, 24%);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* src/colors.css */
|
/* src/colors.css */
|
||||||
[color]:not([color=standard]) {
|
[color]:not([color=standard]) {
|
||||||
--primary: hsl(var(--hue), 100%, var(--accent-luma));
|
--primary: hsl(var(--hue), 100%, var(--accent-luma));
|
||||||
@@ -238,6 +163,143 @@ body[theme=dark] [color]:not([color=standard]).subtle-background {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* src/base.css */
|
||||||
|
#home-page,
|
||||||
|
#home-page #chat-section,
|
||||||
|
#chat-page,
|
||||||
|
#chat-page #main > div {
|
||||||
|
animation: slide-up var(--animation-duration) ease;
|
||||||
|
}
|
||||||
|
#background-wrapper {
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
left: var(--safe-area-left);
|
||||||
|
right: var(--safe-area-right);
|
||||||
|
bottom: 0px;
|
||||||
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
#background-wrapper div {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: -80px;
|
||||||
|
left: -80px;
|
||||||
|
right: -80px;
|
||||||
|
bottom: -80px;
|
||||||
|
z-index: -1;
|
||||||
|
pointer-events: none;
|
||||||
|
filter: blur(40px);
|
||||||
|
}
|
||||||
|
#background-wrapper #sky {
|
||||||
|
left: -100%;
|
||||||
|
bottom: -50%;
|
||||||
|
--color-1: hsl(188, 100%, 83%);
|
||||||
|
--color-2: hsl(194, 72%, 56%);
|
||||||
|
background-image: radial-gradient(var(--color-1), var(--color-2));
|
||||||
|
}
|
||||||
|
#background-wrapper #grass-1 {
|
||||||
|
--color-1: hsl(150, 100%, 30%);
|
||||||
|
--color-2: hsl(150, 100%, 25%);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(
|
||||||
|
350deg,
|
||||||
|
var(--color-1),
|
||||||
|
var(--color-2) 30%,
|
||||||
|
transparent 40%);
|
||||||
|
}
|
||||||
|
#background-wrapper #grass-2 {
|
||||||
|
--color-1: hsl(110, 100%, 40%);
|
||||||
|
--color-2: hsl(110, 100%, 35%);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(
|
||||||
|
9deg,
|
||||||
|
var(--color-1),
|
||||||
|
var(--color-2) 30%,
|
||||||
|
transparent 35%);
|
||||||
|
}
|
||||||
|
body[theme=dark] #background-wrapper {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
body[theme=dark] #background-wrapper #sky {
|
||||||
|
--color-1: hsl(188, 100%, 30%);
|
||||||
|
--color-2: hsl(194, 72%, 24%);
|
||||||
|
}
|
||||||
|
body[theme=dark] #background-wrapper #grass-1 {
|
||||||
|
--color-1: hsl(120, 30%, 30%);
|
||||||
|
--color-2: hsl(120, 30%, 24%);
|
||||||
|
}
|
||||||
|
body[theme=dark] #background-wrapper #grass-2 {
|
||||||
|
--color-1: hsl(110, 60%, 30%);
|
||||||
|
--color-2: hsl(110, 50%, 24%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* src/View/homePage.css */
|
||||||
|
#home-page > div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: var(--large-gap);
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-x: scroll;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
#home-page > div > div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: start;
|
||||||
|
gap: var(--gap-between-tiles);
|
||||||
|
padding: var(--content-padding);
|
||||||
|
padding-top: calc(var(--header-height) + var(--content-margin));
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
scroll-snap-align: center;
|
||||||
|
}
|
||||||
|
#home-page #overview-section,
|
||||||
|
#home-page #chat-section {
|
||||||
|
padding-bottom: calc(var(--content-padding) + var(--header-height) + var(--safe-area-bottom));
|
||||||
|
}
|
||||||
|
#home-page #chat-grid {
|
||||||
|
margin-top: var(--content-padding);
|
||||||
|
display: grid;
|
||||||
|
gap: var(--gap-between-tiles);
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
||||||
|
}
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
#home-page > div {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
#home-page #overview-section {
|
||||||
|
width: 20rem;
|
||||||
|
min-width: 20rem;
|
||||||
|
}
|
||||||
|
#home-page #chat-section {
|
||||||
|
flex: 1;
|
||||||
|
min-width: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
#home-page #overview-section,
|
||||||
|
#home-page #chat-section {
|
||||||
|
padding-left: 3rem;
|
||||||
|
padding-right: 3rem;
|
||||||
|
}
|
||||||
|
#home-page #chat-grid {
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
#home-page #overview-section {
|
||||||
|
width: var(--max-input-width);
|
||||||
|
min-width: var(--max-input-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* src/View/chatPage.css */
|
/* src/View/chatPage.css */
|
||||||
#chat-page-wrapper {
|
#chat-page-wrapper {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -408,179 +470,95 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* src/View/homePage.css */
|
/* src/View/ChatPages/taskPage.css */
|
||||||
#home-page > div {
|
#chat-page > div > #main > #task-page > .pane-wrapper > .pane > .main-content {
|
||||||
display: flex;
|
width: 100%;
|
||||||
flex-direction: row;
|
max-width: 100%;
|
||||||
gap: var(--large-gap);
|
|
||||||
scroll-snap-type: x mandatory;
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
overflow: hidden;
|
|
||||||
overflow-x: scroll;
|
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
#home-page > div > div {
|
#chat-page > div > #main > #task-page > .pane-wrapper > .pane > .main-content > div {
|
||||||
|
animation: slide-up var(--animation-duration);
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page .task-grid {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: start;
|
|
||||||
gap: var(--gap-between-tiles);
|
gap: var(--gap-between-tiles);
|
||||||
padding: var(--content-padding);
|
padding: var(--content-padding);
|
||||||
padding-top: calc(var(--header-height) + var(--content-margin));
|
}
|
||||||
|
#chat-page > div > #main > #task-page .kanban-board-wrapper,
|
||||||
|
#chat-page > div > #main > #task-page .status-page-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: start;
|
||||||
|
gap: var(--large-gap);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
scroll-snap-align: center;
|
|
||||||
}
|
|
||||||
#home-page #overview-section,
|
|
||||||
#home-page #chat-section {
|
|
||||||
padding-bottom: calc(var(--content-padding) + var(--header-height) + var(--safe-area-bottom));
|
|
||||||
}
|
|
||||||
#home-page #chat-grid {
|
|
||||||
margin-top: var(--content-padding);
|
|
||||||
display: grid;
|
|
||||||
gap: var(--gap-between-tiles);
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
|
||||||
}
|
|
||||||
@media (min-width: 640px) {
|
|
||||||
#home-page > div {
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
#home-page #overview-section {
|
|
||||||
width: 20rem;
|
|
||||||
min-width: 20rem;
|
|
||||||
}
|
|
||||||
#home-page #chat-section {
|
|
||||||
flex: 1;
|
|
||||||
min-width: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
#home-page #overview-section,
|
|
||||||
#home-page #chat-section {
|
|
||||||
padding-left: 3rem;
|
|
||||||
padding-right: 3rem;
|
|
||||||
}
|
|
||||||
#home-page #chat-grid {
|
|
||||||
margin-top: 3rem;
|
|
||||||
}
|
|
||||||
#home-page #overview-section {
|
|
||||||
width: var(--max-input-width);
|
|
||||||
min-width: var(--max-input-width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* src/View/ChatPages/calendarPage.css */
|
|
||||||
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper {
|
|
||||||
display: flex;
|
|
||||||
padding: var(--gap-between-tiles);
|
|
||||||
gap: var(--gap-between-tiles);
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper > input {
|
|
||||||
min-height: unset;
|
|
||||||
height: calc(var(--control-height) - 2 * var(--gap-between-tiles));
|
|
||||||
appearance: textfield;
|
|
||||||
-moz-appearance: textfield;
|
|
||||||
padding-right: 0px;
|
|
||||||
}
|
|
||||||
#calendar-page .input-wrapper > input::-webkit-outer-spin-button,
|
|
||||||
#calendar-page .input-wrapper > input::-webkit-innner-spin-button {
|
|
||||||
appearance: none;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper > .year-input {
|
|
||||||
width: 4.4rem;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper > .month-input {
|
|
||||||
width: 3.1rem;
|
|
||||||
}
|
|
||||||
@media (max-width: 1024px) {
|
|
||||||
#chat-page > div > #main > #calendar-page {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #calendar-page .grid-pane-wrapper {
|
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* src/View/Components/monthGrid.css */
|
|
||||||
.month-grid-wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: var(--gap-between-tiles);
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
|
||||||
.month-grid-wrapper .day-labels {
|
|
||||||
flex: 0;
|
|
||||||
padding: var(--content-padding);
|
padding: var(--content-padding);
|
||||||
padding-bottom: 0px;
|
|
||||||
}
|
}
|
||||||
.month-grid-wrapper > div {
|
#chat-page > div > #main > #task-page .kanban-board-wrapper .kanban-column,
|
||||||
display: grid;
|
#chat-page > div > #main > #task-page .status-grid-wrapper .status-column {
|
||||||
gap: var(--gap-between-tiles);
|
|
||||||
grid-template-columns: repeat(7, minmax(0px, 1fr));
|
|
||||||
animation: slide-up var(--animation-duration);
|
|
||||||
}
|
|
||||||
.month-grid {
|
|
||||||
overflow: visible;
|
|
||||||
padding: var(--content-padding);
|
|
||||||
padding-top: 0px;
|
|
||||||
flex: 1;
|
|
||||||
grid-auto-rows: 1fr;
|
|
||||||
}
|
|
||||||
.month-grid .tile {
|
|
||||||
animation: slide-up var(--animation-duration);
|
|
||||||
overflow: hidden;
|
|
||||||
align-items: start;
|
|
||||||
}
|
|
||||||
.month-grid .tile[today] b {
|
|
||||||
color: var(--primary);
|
|
||||||
}
|
|
||||||
.month-grid .tile > div {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.month-grid .tile .event-count {
|
|
||||||
display: none;
|
|
||||||
background-color: var(--text-normal);
|
|
||||||
color: var(--background);
|
|
||||||
opacity: 0.6;
|
|
||||||
border-radius: 100%;
|
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
font-size: 0.6rem;
|
|
||||||
font-weight: bold;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.month-grid .tile .event-count[has-events] {
|
|
||||||
background-color: var(--primary);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.month-grid .tile .event-list {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
gap: var(--gap-between-tiles);
|
gap: var(--gap-between-tiles);
|
||||||
}
|
}
|
||||||
.month-grid .tile .event-list span {
|
#chat-page > div > #main > #task-page .property-input-wrapper {
|
||||||
animation: slide-up var(--animation-duration);
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
@media (max-width: 640px) and (max-height: 1200px) {
|
#chat-page > div > #main > #task-page .kanban-board-wrapper .kanban-column,
|
||||||
.month-grid .tile {
|
#chat-page > div > #main > #task-page .property-input-wrapper,
|
||||||
padding: 0px;
|
#chat-page > div > #main > #task-page .status-grid-wrapper .status-column,
|
||||||
|
#chat-page > div > #main > #task-page .status-name-row > *,
|
||||||
|
#chat-page > div > #main > #task-page .status-name-row::before {
|
||||||
|
width: 18rem;
|
||||||
|
min-width: 18rem;
|
||||||
|
max-width: 18rem;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page .status-name-row,
|
||||||
|
#chat-page > div > #main > #task-page .status-grid-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--large-gap);
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page .status-page-content,
|
||||||
|
#chat-page > div > #main > #task-page .status-grid-wrapper {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page .status-name-row::before {
|
||||||
|
content: "";
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page .board-close-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page .board-toggle-button {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page[isshowingboard][showingboardlist=false] #board-list {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
#chat-page > div > #main > #task-page .task-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||||
}
|
}
|
||||||
.month-grid .tile > div {
|
}
|
||||||
align-items: center;
|
@media (max-width: 1024px) {
|
||||||
justify-content: center;
|
#chat-page > div > #main > #task-page #board-list {
|
||||||
|
display: false;
|
||||||
}
|
}
|
||||||
.month-grid .tile .event-count {
|
#chat-page > div > #main > #task-page #board-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page[isshowingboard] #board-list {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page[isshowingboard] #board-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.month-grid .tile .event-list {
|
#chat-page > div > #main > #task-page .board-close-button {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
#chat-page > div > #main > #task-page .board-toggle-button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -810,95 +788,117 @@ body[showing-chat] #chat-page-wrapper {
|
|||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* src/View/ChatPages/taskPage.css */
|
/* src/View/ChatPages/calendarPage.css */
|
||||||
#chat-page > div > #main > #task-page > .pane-wrapper > .pane > .main-content {
|
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper {
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page > .pane-wrapper > .pane > .main-content > div {
|
|
||||||
animation: slide-up var(--animation-duration);
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page .task-grid {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
padding: var(--gap-between-tiles);
|
||||||
gap: var(--gap-between-tiles);
|
|
||||||
padding: var(--content-padding);
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page .kanban-board-wrapper,
|
|
||||||
#chat-page > div > #main > #task-page .status-page-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: start;
|
|
||||||
gap: var(--large-gap);
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
padding: var(--content-padding);
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page .kanban-board-wrapper .kanban-column,
|
|
||||||
#chat-page > div > #main > #task-page .status-grid-wrapper .status-column {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: var(--gap-between-tiles);
|
gap: var(--gap-between-tiles);
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page .property-input-wrapper {
|
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper > input {
|
||||||
display: flex;
|
min-height: unset;
|
||||||
flex-direction: row;
|
height: calc(var(--control-height) - 2 * var(--gap-between-tiles));
|
||||||
|
appearance: textfield;
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page .kanban-board-wrapper .kanban-column,
|
#calendar-page .input-wrapper > input::-webkit-outer-spin-button,
|
||||||
#chat-page > div > #main > #task-page .property-input-wrapper,
|
#calendar-page .input-wrapper > input::-webkit-innner-spin-button {
|
||||||
#chat-page > div > #main > #task-page .status-grid-wrapper .status-column,
|
appearance: none;
|
||||||
#chat-page > div > #main > #task-page .status-name-row > *,
|
-webkit-appearance: none;
|
||||||
#chat-page > div > #main > #task-page .status-name-row::before {
|
margin: 0px;
|
||||||
width: 18rem;
|
|
||||||
min-width: 18rem;
|
|
||||||
max-width: 18rem;
|
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page .status-name-row,
|
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper > .year-input {
|
||||||
#chat-page > div > #main > #task-page .status-grid-wrapper {
|
width: 4.4rem;
|
||||||
display: flex;
|
|
||||||
gap: var(--large-gap);
|
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page .status-page-content,
|
#chat-page > div > #main > #calendar-page > .pane-wrapper > .pane > .toolbar .input-wrapper > .month-input {
|
||||||
#chat-page > div > #main > #task-page .status-grid-wrapper {
|
width: 3.1rem;
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page .status-name-row::before {
|
|
||||||
content: "";
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page .board-close-button {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page .board-toggle-button {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page[isshowingboard][showingboardlist=false] #board-list {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
@media (min-width: 640px) {
|
|
||||||
#chat-page > div > #main > #task-page .task-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
#chat-page > div > #main > #task-page #board-list {
|
#chat-page > div > #main > #calendar-page {
|
||||||
display: false;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page #board-content {
|
#chat-page > div > #main > #calendar-page .grid-pane-wrapper {
|
||||||
display: none;
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page[isshowingboard] #board-list {
|
}
|
||||||
display: none;
|
|
||||||
|
/* src/View/Components/monthGrid.css */
|
||||||
|
.month-grid-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--gap-between-tiles);
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.month-grid-wrapper .day-labels {
|
||||||
|
flex: 0;
|
||||||
|
padding: var(--content-padding);
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
.month-grid-wrapper > div {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--gap-between-tiles);
|
||||||
|
grid-template-columns: repeat(7, minmax(0px, 1fr));
|
||||||
|
animation: slide-up var(--animation-duration);
|
||||||
|
}
|
||||||
|
.month-grid {
|
||||||
|
overflow: visible;
|
||||||
|
padding: var(--content-padding);
|
||||||
|
padding-top: 0px;
|
||||||
|
flex: 1;
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
}
|
||||||
|
.month-grid .tile {
|
||||||
|
animation: slide-up var(--animation-duration);
|
||||||
|
overflow: hidden;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
.month-grid .tile[today] b {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
.month-grid .tile > div {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.month-grid .tile .event-count {
|
||||||
|
display: none;
|
||||||
|
background-color: var(--text-normal);
|
||||||
|
color: var(--background);
|
||||||
|
opacity: 0.6;
|
||||||
|
border-radius: 100%;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: bold;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.month-grid .tile .event-count[has-events] {
|
||||||
|
background-color: var(--primary);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.month-grid .tile .event-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
gap: var(--gap-between-tiles);
|
||||||
|
}
|
||||||
|
.month-grid .tile .event-list span {
|
||||||
|
animation: slide-up var(--animation-duration);
|
||||||
|
}
|
||||||
|
@media (max-width: 640px) and (max-height: 1200px) {
|
||||||
|
.month-grid .tile {
|
||||||
|
padding: 0px;
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page[isshowingboard] #board-content {
|
.month-grid .tile > div {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.month-grid .tile .event-count {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
#chat-page > div > #main > #task-page .board-close-button {
|
.month-grid .tile .event-list {
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
#chat-page > div > #main > #task-page .board-toggle-button {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+4289
-4282
File diff suppressed because it is too large
Load Diff
Generated
+70
-5
@@ -6,10 +6,14 @@
|
|||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"bloatless-react": "^1.3.11",
|
"bloatless-react": "1.3.14",
|
||||||
"esbuild": "^0.23.0",
|
"esbuild": "^0.23.1",
|
||||||
"udn-frontend": "^1.0.9",
|
"udn-frontend": "^1.0.9",
|
||||||
"uuid": "^10.0.0"
|
"uuid": "^10.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier-plugin-organize-imports": "^4.3.0",
|
||||||
|
"prettier-plugin-sort-imports": "^1.8.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
@@ -403,9 +407,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/bloatless-react": {
|
"node_modules/bloatless-react": {
|
||||||
"version": "1.3.12",
|
"version": "1.3.14",
|
||||||
"resolved": "https://registry.npmjs.org/bloatless-react/-/bloatless-react-1.3.12.tgz",
|
"resolved": "https://registry.npmjs.org/bloatless-react/-/bloatless-react-1.3.14.tgz",
|
||||||
"integrity": "sha512-JEyAA8JKRVuv6swl7TUzOX3vJ9QdV25cQvTqjLyaQlNKfDVPAtLVR8HMfGdpiOC2mr866FghT9OotWKfWd665w==",
|
"integrity": "sha512-Y4v8RnZeggUozvqHsG6QkZI6AvwxtumaJ4NLPQRbCB7/MuuxA2cc6U+Cw4SiXPY1y9TAarI75xOWh8CNK6wijA==",
|
||||||
"license": "SEE LICENSE IN LICENSE",
|
"license": "SEE LICENSE IN LICENSE",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"uuid": "^13.0.0"
|
"uuid": "^13.0.0"
|
||||||
@@ -463,6 +467,67 @@
|
|||||||
"@esbuild/win32-x64": "0.23.1"
|
"@esbuild/win32-x64": "0.23.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "3.8.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
|
||||||
|
"integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin/prettier.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prettier-plugin-organize-imports": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-FxFz0qFhyBsGdIsb697f/EkvHzi5SZOhWAjxcx2dLt+Q532bAlhswcXGYB1yzjZ69kW8UoadFBw7TyNwlq96Iw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"prettier": ">=2.0",
|
||||||
|
"typescript": ">=2.9",
|
||||||
|
"vue-tsc": "^2.1.0 || 3"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"vue-tsc": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prettier-plugin-sort-imports": {
|
||||||
|
"version": "1.8.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-1.8.11.tgz",
|
||||||
|
"integrity": "sha512-ApmZkEmNh2Fi6TAcYNgUR15rsP1+omX43+8neY+MXfNZ7JQwrqSdjzKhLUYTtaLo52aaC9gCs+lJaYSU8oSJJA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"prettier": "^3.1.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/udn-frontend": {
|
"node_modules/udn-frontend": {
|
||||||
"version": "1.0.9",
|
"version": "1.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/udn-frontend/-/udn-frontend-1.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/udn-frontend/-/udn-frontend-1.0.9.tgz",
|
||||||
|
|||||||
@@ -8,5 +8,8 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "esbuild src/index.tsx --bundle --outdir=dist"
|
"build": "esbuild src/index.tsx --bundle --outdir=dist"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier-plugin-sort-imports": "^1.8.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,30 @@
|
|||||||
|
// cleanup: Phase A
|
||||||
|
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
import { Message } from "udn-frontend";
|
||||||
import ChatModel, { ChatMessage } from "./chatModel";
|
import ChatModel, { ChatMessage } from "./chatModel";
|
||||||
import StorageModel, {
|
import StorageModel, {
|
||||||
StorageModelSubPaths,
|
StorageModelSubPaths,
|
||||||
filePaths,
|
filePaths,
|
||||||
} from "../Global/storageModel";
|
} from "../Global/storageModel";
|
||||||
|
|
||||||
import ConnectionModel from "../Global/connectionModel";
|
|
||||||
import { Message } from "udn-frontend";
|
|
||||||
import SettingsModel from "../Global/settingsModel";
|
import SettingsModel from "../Global/settingsModel";
|
||||||
import { v4 } from "uuid";
|
import ConnectionModel from "../Global/connectionModel";
|
||||||
|
|
||||||
export default class ChatListModel {
|
export default class ChatListModel {
|
||||||
|
// models
|
||||||
readonly storageModel: StorageModel;
|
readonly storageModel: StorageModel;
|
||||||
readonly settingsModel: SettingsModel;
|
readonly settingsModel: SettingsModel;
|
||||||
readonly connectionModel: ConnectionModel;
|
readonly connectionModel: ConnectionModel;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
chatModels = new Set<ChatModel>();
|
readonly chatModels = new Set<ChatModel>();
|
||||||
|
|
||||||
// handlers
|
// chat handling
|
||||||
messageHandler = (data: Message): void => {
|
readonly addChatModel = (chatModel: ChatModel) => {
|
||||||
const channel: string | undefined = data.messageChannel;
|
|
||||||
const body: string | undefined = data.messageBody;
|
|
||||||
if (channel == undefined) return;
|
|
||||||
if (body == undefined) return;
|
|
||||||
|
|
||||||
this.routeMessageToCorrectChatModel(channel, (chatModel: ChatModel) =>
|
|
||||||
chatModel.handleMessage(body),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
messageSentHandler = (chatMessage: ChatMessage): void => {
|
|
||||||
const channel: string = chatMessage.channel;
|
|
||||||
|
|
||||||
this.routeMessageToCorrectChatModel(channel, (chatModel: ChatModel) =>
|
|
||||||
chatModel.handleMessageSent(chatMessage),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// methods
|
|
||||||
routeMessageToCorrectChatModel = (
|
|
||||||
channel: string,
|
|
||||||
fn: (chatModel: ChatModel) => void,
|
|
||||||
): void => {
|
|
||||||
const allChannels: string[] = channel.split("/");
|
|
||||||
|
|
||||||
for (const chatModel of this.chatModels) {
|
|
||||||
for (const channel of allChannels) {
|
|
||||||
if (channel != chatModel.info.primaryChannel) continue;
|
|
||||||
fn(chatModel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// storage
|
|
||||||
addChatModel = (chatModel: ChatModel) => {
|
|
||||||
this.chatModels.add(chatModel);
|
this.chatModels.add(chatModel);
|
||||||
};
|
};
|
||||||
|
|
||||||
createChat = (primaryChannel: string): ChatModel => {
|
readonly createChat = (primaryChannel: string): ChatModel => {
|
||||||
const id: string = v4();
|
const id: string = v4();
|
||||||
|
|
||||||
const chatModel = new ChatModel(
|
const chatModel = new ChatModel(
|
||||||
@@ -74,12 +40,48 @@ export default class ChatListModel {
|
|||||||
return chatModel;
|
return chatModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
untrackChat = (chat: ChatModel): void => {
|
readonly untrackChat = (chat: ChatModel): void => {
|
||||||
this.chatModels.delete(chat);
|
this.chatModels.delete(chat);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// message handlers
|
||||||
|
readonly messageHandler = (data: Message): void => {
|
||||||
|
const channel: string | undefined = data.messageChannel;
|
||||||
|
const body: string | undefined = data.messageBody;
|
||||||
|
if (channel == undefined) return;
|
||||||
|
if (body == undefined) return;
|
||||||
|
|
||||||
|
this.routeMessageToCorrectChatModel(channel, (chatModel: ChatModel) =>
|
||||||
|
chatModel.handleMessage(body),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
readonly messageSentHandler = (chatMessage: ChatMessage): void => {
|
||||||
|
const channel: string = chatMessage.channel;
|
||||||
|
|
||||||
|
this.routeMessageToCorrectChatModel(channel, (chatModel: ChatModel) =>
|
||||||
|
chatModel.handleMessageSent(chatMessage),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// util
|
||||||
|
readonly routeMessageToCorrectChatModel = (
|
||||||
|
channel: string,
|
||||||
|
fn: (chatModel: ChatModel) => void,
|
||||||
|
): void => {
|
||||||
|
const allChannels: string[] = channel.split("/");
|
||||||
|
|
||||||
|
for (const chatModel of this.chatModels) {
|
||||||
|
for (const channel of allChannels) {
|
||||||
|
if (channel != chatModel.info.primaryChannel) continue;
|
||||||
|
fn(chatModel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// load
|
// load
|
||||||
loadChats = (): void => {
|
readonly loadChats = (): void => {
|
||||||
const chatDir = StorageModel.getPath(
|
const chatDir = StorageModel.getPath(
|
||||||
StorageModelSubPaths.Chat,
|
StorageModelSubPaths.Chat,
|
||||||
filePaths.chat.base,
|
filePaths.chat.base,
|
||||||
|
|||||||
+46
-44
@@ -1,11 +1,7 @@
|
|||||||
// this file is responsible for managing chats.
|
// cleanup: Phase A
|
||||||
|
|
||||||
import {
|
import { v4 } from "uuid";
|
||||||
checkMatchesObjectStructure,
|
import ChatListModel from "./chatListModel";
|
||||||
DATA_VERSION,
|
|
||||||
ValidObject,
|
|
||||||
} from "../Utility/typeSafety";
|
|
||||||
import FileModel, { FileContent } from "../Files/fileModel";
|
|
||||||
import {
|
import {
|
||||||
HandlerManager,
|
HandlerManager,
|
||||||
createTimestamp,
|
createTimestamp,
|
||||||
@@ -13,24 +9,27 @@ import {
|
|||||||
parseValidObject,
|
parseValidObject,
|
||||||
stringify,
|
stringify,
|
||||||
} from "../Utility/utility";
|
} from "../Utility/utility";
|
||||||
|
import {
|
||||||
|
DATA_VERSION,
|
||||||
|
ValidObject,
|
||||||
|
checkMatchesObjectStructure,
|
||||||
|
} from "../Utility/typeSafety";
|
||||||
|
import { decryptString, encryptString } from "../Utility/crypto";
|
||||||
import StorageModel, {
|
import StorageModel, {
|
||||||
StorageModelSubPaths,
|
StorageModelSubPaths,
|
||||||
filePaths,
|
filePaths,
|
||||||
} from "../Global/storageModel";
|
} from "../Global/storageModel";
|
||||||
import { decryptString, encryptString } from "../Utility/crypto";
|
|
||||||
|
|
||||||
import ChatListModel from "./chatListModel";
|
|
||||||
import { Colors } from "../../colors";
|
|
||||||
import ConnectionModel from "../Global/connectionModel";
|
|
||||||
import SettingsModel from "../Global/settingsModel";
|
import SettingsModel from "../Global/settingsModel";
|
||||||
import { v4 } from "uuid";
|
import ConnectionModel from "../Global/connectionModel";
|
||||||
|
import FileModel, { FileContent } from "../Files/fileModel";
|
||||||
|
import { Colors } from "../../colors";
|
||||||
|
|
||||||
export default class ChatModel {
|
export default class ChatModel {
|
||||||
|
// models
|
||||||
readonly connectionModel: ConnectionModel;
|
readonly connectionModel: ConnectionModel;
|
||||||
readonly storageModel: StorageModel;
|
readonly storageModel: StorageModel;
|
||||||
readonly settingsModel: SettingsModel;
|
readonly settingsModel: SettingsModel;
|
||||||
readonly chatListModel: ChatListModel;
|
readonly chatListModel: ChatListModel;
|
||||||
|
|
||||||
readonly fileModel: FileModel;
|
readonly fileModel: FileModel;
|
||||||
|
|
||||||
// data
|
// data
|
||||||
@@ -38,61 +37,62 @@ export default class ChatModel {
|
|||||||
info: ChatInfo;
|
info: ChatInfo;
|
||||||
color: Colors;
|
color: Colors;
|
||||||
|
|
||||||
|
get secondaryChannels(): string[] {
|
||||||
|
return this.info.secondaryChannels.sort(localeCompare);
|
||||||
|
}
|
||||||
|
|
||||||
|
// handler managers
|
||||||
chatMessageHandlerManager: HandlerManager<ChatMessage> =
|
chatMessageHandlerManager: HandlerManager<ChatMessage> =
|
||||||
new HandlerManager();
|
new HandlerManager();
|
||||||
readonly reactionHandlerManager: HandlerManager<ChatMessageReaction> =
|
readonly reactionHandlerManager: HandlerManager<ChatMessageReaction> =
|
||||||
new HandlerManager();
|
new HandlerManager();
|
||||||
|
|
||||||
get secondaryChannels(): string[] {
|
|
||||||
return this.info.secondaryChannels.sort(localeCompare);
|
|
||||||
}
|
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
getBasePath = (): string[] => {
|
readonly getBasePath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.Chat,
|
StorageModelSubPaths.Chat,
|
||||||
filePaths.chat.chatBase(this.id),
|
filePaths.chat.chatBase(this.id),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getInfoPath = (): string[] => {
|
readonly getInfoPath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.Chat,
|
StorageModelSubPaths.Chat,
|
||||||
filePaths.chat.info(this.id),
|
filePaths.chat.info(this.id),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getColorPath = (): string[] => {
|
readonly getColorPath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.Chat,
|
StorageModelSubPaths.Chat,
|
||||||
filePaths.chat.color(this.id),
|
filePaths.chat.color(this.id),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getMessageDirPath = (): string[] => {
|
readonly getMessageDirPath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.Chat,
|
StorageModelSubPaths.Chat,
|
||||||
filePaths.chat.messages(this.id),
|
filePaths.chat.messages(this.id),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getMessagePath = (id: string): string[] => {
|
readonly getMessagePath = (id: string): string[] => {
|
||||||
return [...this.getMessageDirPath(), id];
|
return [...this.getMessageDirPath(), id];
|
||||||
};
|
};
|
||||||
|
|
||||||
getReactionDirPath = (): string[] => {
|
readonly getReactionDirPath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.Chat,
|
StorageModelSubPaths.Chat,
|
||||||
filePaths.chat.reactions(this.id),
|
filePaths.chat.reactions(this.id),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getReactionPath = (id: string): string[] => {
|
readonly getReactionPath = (id: string): string[] => {
|
||||||
return [...this.getReactionDirPath(), id];
|
return [...this.getReactionDirPath(), id];
|
||||||
};
|
};
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
handleMessage = (body: string): void => {
|
readonly handleMessage = (body: string): void => {
|
||||||
const chatMessage: ChatMessage | null = parseValidObject(
|
const chatMessage: ChatMessage | null = parseValidObject(
|
||||||
body,
|
body,
|
||||||
ChatMessageReference,
|
ChatMessageReference,
|
||||||
@@ -107,7 +107,7 @@ export default class ChatModel {
|
|||||||
this.setReadStatus(true);
|
this.setReadStatus(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleReaction = (reaction: ChatMessageReaction | any): void => {
|
readonly handleReaction = (reaction: ChatMessageReaction | any): void => {
|
||||||
if (
|
if (
|
||||||
!checkMatchesObjectStructure(reaction, ChatMessageReactionReference)
|
!checkMatchesObjectStructure(reaction, ChatMessageReactionReference)
|
||||||
)
|
)
|
||||||
@@ -122,35 +122,35 @@ export default class ChatModel {
|
|||||||
this.reactionHandlerManager.trigger(reaction);
|
this.reactionHandlerManager.trigger(reaction);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleMessageSent = (chatMessage: ChatMessage): void => {
|
readonly handleMessageSent = (chatMessage: ChatMessage): void => {
|
||||||
chatMessage.status = ChatMessageStatuses.Sent;
|
chatMessage.status = ChatMessageStatuses.Sent;
|
||||||
this.addMessage(chatMessage);
|
this.addMessage(chatMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
setPrimaryChannel = (primaryChannel: string): void => {
|
readonly setPrimaryChannel = (primaryChannel: string): void => {
|
||||||
this.info.primaryChannel = primaryChannel;
|
this.info.primaryChannel = primaryChannel;
|
||||||
this.storeInfo();
|
this.storeInfo();
|
||||||
this.subscribe();
|
this.subscribe();
|
||||||
};
|
};
|
||||||
|
|
||||||
setSecondaryChannels = (secondaryChannels: string[]): void => {
|
readonly setSecondaryChannels = (secondaryChannels: string[]): void => {
|
||||||
this.info.secondaryChannels = secondaryChannels;
|
this.info.secondaryChannels = secondaryChannels;
|
||||||
this.storeInfo();
|
this.storeInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncryptionKey = (key: string): void => {
|
readonly setEncryptionKey = (key: string): void => {
|
||||||
this.info.encryptionKey = key;
|
this.info.encryptionKey = key;
|
||||||
this.storeInfo();
|
this.storeInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
setColor = (color: Colors): void => {
|
readonly setColor = (color: Colors): void => {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.storeColor();
|
this.storeColor();
|
||||||
};
|
};
|
||||||
|
|
||||||
// messaging
|
// messaging
|
||||||
addMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
readonly addMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
||||||
await this.decryptMessage(chatMessage);
|
await this.decryptMessage(chatMessage);
|
||||||
|
|
||||||
// message
|
// message
|
||||||
@@ -166,7 +166,7 @@ export default class ChatModel {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getNameAndChannel = (): [string, string] | false => {
|
readonly getNameAndChannel = (): [string, string] | false => {
|
||||||
const senderName: string = this.settingsModel.username;
|
const senderName: string = this.settingsModel.username;
|
||||||
if (senderName == "") return false;
|
if (senderName == "") return false;
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ export default class ChatModel {
|
|||||||
return [senderName, combinedChannel];
|
return [senderName, combinedChannel];
|
||||||
};
|
};
|
||||||
|
|
||||||
sendMessage = async (
|
readonly sendMessage = async (
|
||||||
body: string,
|
body: string,
|
||||||
inlineReplyId?: string,
|
inlineReplyId?: string,
|
||||||
fileContent?: FileContent<string>,
|
fileContent?: FileContent<string>,
|
||||||
@@ -203,7 +203,9 @@ export default class ChatModel {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
decryptMessage = async (chatMessage: ChatMessage): Promise<void> => {
|
readonly decryptMessage = async (
|
||||||
|
chatMessage: ChatMessage,
|
||||||
|
): Promise<void> => {
|
||||||
const decryptedBody: string = await decryptString(
|
const decryptedBody: string = await decryptString(
|
||||||
chatMessage.body,
|
chatMessage.body,
|
||||||
this.info.encryptionKey,
|
this.info.encryptionKey,
|
||||||
@@ -216,7 +218,7 @@ export default class ChatModel {
|
|||||||
chatMessage.stringifiedFile = decryptedFile;
|
chatMessage.stringifiedFile = decryptedFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
sendReaction = async (
|
readonly sendReaction = async (
|
||||||
messageId: string,
|
messageId: string,
|
||||||
content: ReactionSymbols,
|
content: ReactionSymbols,
|
||||||
isDeleting?: boolean,
|
isDeleting?: boolean,
|
||||||
@@ -235,25 +237,25 @@ export default class ChatModel {
|
|||||||
this.handleReaction(reaction);
|
this.handleReaction(reaction);
|
||||||
};
|
};
|
||||||
|
|
||||||
subscribe = (): void => {
|
readonly subscribe = (): void => {
|
||||||
this.connectionModel.addChannel(this.info.primaryChannel);
|
this.connectionModel.addChannel(this.info.primaryChannel);
|
||||||
};
|
};
|
||||||
|
|
||||||
setReadStatus = (hasUnreadMessages: boolean): void => {
|
readonly setReadStatus = (hasUnreadMessages: boolean): void => {
|
||||||
this.info.hasUnreadMessages = hasUnreadMessages;
|
this.info.hasUnreadMessages = hasUnreadMessages;
|
||||||
this.storeInfo();
|
this.storeInfo();
|
||||||
};
|
};
|
||||||
|
|
||||||
// storage
|
// storage
|
||||||
storeInfo = (): void => {
|
readonly storeInfo = (): void => {
|
||||||
this.storageModel.writeStringifiable(this.getInfoPath(), this.info);
|
this.storageModel.writeStringifiable(this.getInfoPath(), this.info);
|
||||||
};
|
};
|
||||||
|
|
||||||
storeColor = (): void => {
|
readonly storeColor = (): void => {
|
||||||
this.storageModel.write(this.getColorPath(), this.color);
|
this.storageModel.write(this.getColorPath(), this.color);
|
||||||
};
|
};
|
||||||
|
|
||||||
delete = () => {
|
readonly delete = () => {
|
||||||
// untrack
|
// untrack
|
||||||
this.chatListModel.untrackChat(this);
|
this.chatListModel.untrackChat(this);
|
||||||
|
|
||||||
@@ -263,7 +265,7 @@ export default class ChatModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// load
|
// load
|
||||||
loadInfo = (): void => {
|
readonly loadInfo = (): void => {
|
||||||
const info: ChatInfo | null = this.storageModel.readStringifiable(
|
const info: ChatInfo | null = this.storageModel.readStringifiable(
|
||||||
this.getInfoPath(),
|
this.getInfoPath(),
|
||||||
ChatInfoReference,
|
ChatInfoReference,
|
||||||
@@ -275,7 +277,7 @@ export default class ChatModel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadColor = (): void => {
|
readonly loadColor = (): void => {
|
||||||
const path: string[] = this.getColorPath();
|
const path: string[] = this.getColorPath();
|
||||||
const color: string | null = this.storageModel.read(path);
|
const color: string | null = this.storageModel.read(path);
|
||||||
if (!color) {
|
if (!color) {
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
// this file is responsible for managing boards within chats and tasks within boards.
|
// cleanup: Phase A
|
||||||
|
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
import FileModel, { FileContent, FileModelSubPath } from "./fileModel";
|
||||||
|
import CalendarModel from "./calendarModel";
|
||||||
|
import { HandlerManager } from "../Utility/utility";
|
||||||
import {
|
import {
|
||||||
DATA_VERSION,
|
DATA_VERSION,
|
||||||
checkMatchesObjectStructure,
|
checkMatchesObjectStructure,
|
||||||
} from "../Utility/typeSafety";
|
} from "../Utility/typeSafety";
|
||||||
import FileModel, { FileContent, FileModelSubPath } from "./fileModel";
|
import StorageModel from "../Global/storageModel";
|
||||||
|
import SettingsModel from "../Global/settingsModel";
|
||||||
import CalendarModel from "./calendarModel";
|
|
||||||
import ChatModel from "../Chat/chatModel";
|
import ChatModel from "../Chat/chatModel";
|
||||||
import { Colors } from "../../colors";
|
import { Colors } from "../../colors";
|
||||||
import { HandlerManager } from "../Utility/utility";
|
|
||||||
import SettingsModel from "../Global/settingsModel";
|
|
||||||
import StorageModel from "../Global/storageModel";
|
|
||||||
import { v4 } from "uuid";
|
|
||||||
|
|
||||||
export default class BoardsAndTasksModel {
|
export default class BoardsAndTasksModel {
|
||||||
readonly storageModel: StorageModel;
|
readonly storageModel: StorageModel;
|
||||||
@@ -27,43 +26,43 @@ export default class BoardsAndTasksModel {
|
|||||||
readonly taskHandlerManager = new HandlerManager<TaskFileContent>();
|
readonly taskHandlerManager = new HandlerManager<TaskFileContent>();
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
getBasePath = (): string[] => {
|
readonly getBasePath = (): string[] => {
|
||||||
return this.fileModel.getModelContainerPath(FileModelSubPath.ModelTask);
|
return this.fileModel.getModelContainerPath(FileModelSubPath.ModelTask);
|
||||||
};
|
};
|
||||||
|
|
||||||
getViewPath = (): string[] => {
|
readonly getViewPath = (): string[] => {
|
||||||
return [...this.getBasePath(), FileModelSubPath.ModelView];
|
return [...this.getBasePath(), FileModelSubPath.ModelView];
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoardFilePath = (boardId: string): string[] => {
|
readonly getBoardFilePath = (boardId: string): string[] => {
|
||||||
return [...this.fileModel.getFilePath(boardId)];
|
return [...this.fileModel.getFilePath(boardId)];
|
||||||
};
|
};
|
||||||
|
|
||||||
getTaskFilePath = (taskId: string): string[] => {
|
readonly getTaskFilePath = (taskId: string): string[] => {
|
||||||
return [...this.fileModel.getFilePath(taskId)];
|
return [...this.fileModel.getFilePath(taskId)];
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoardContainerPath = (): string[] => {
|
readonly getBoardContainerPath = (): string[] => {
|
||||||
return [...this.getBasePath(), TaskModelSubPaths.Boards];
|
return [...this.getBasePath(), TaskModelSubPaths.Boards];
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoardDirectoryPath = (boardId: string): string[] => {
|
readonly getBoardDirectoryPath = (boardId: string): string[] => {
|
||||||
return [...this.getBoardContainerPath(), boardId];
|
return [...this.getBoardContainerPath(), boardId];
|
||||||
};
|
};
|
||||||
|
|
||||||
getTaskContainerPath = (boardId: string): string[] => {
|
readonly getTaskContainerPath = (boardId: string): string[] => {
|
||||||
return [
|
return [
|
||||||
...this.getBoardDirectoryPath(boardId),
|
...this.getBoardDirectoryPath(boardId),
|
||||||
TaskModelSubPaths.BoardTasks,
|
TaskModelSubPaths.BoardTasks,
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
getTaskReferencePath = (boardId: string, fileId: string): string[] => {
|
readonly getTaskReferencePath = (boardId: string, fileId: string): string[] => {
|
||||||
return [...this.getTaskContainerPath(boardId), fileId];
|
return [...this.getTaskContainerPath(boardId), fileId];
|
||||||
};
|
};
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
handleFileContent = (fileContent: FileContent<string>): void => {
|
readonly handleFileContent = (fileContent: FileContent<string>): void => {
|
||||||
if (
|
if (
|
||||||
checkMatchesObjectStructure(
|
checkMatchesObjectStructure(
|
||||||
fileContent,
|
fileContent,
|
||||||
@@ -81,16 +80,16 @@ export default class BoardsAndTasksModel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleBoard = (boardInfoFileContent: BoardInfoFileContent) => {
|
readonly handleBoard = (boardInfoFileContent: BoardInfoFileContent) => {
|
||||||
this.updateBoard(boardInfoFileContent);
|
this.updateBoard(boardInfoFileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleTask = (taskFileContent: TaskFileContent) => {
|
readonly handleTask = (taskFileContent: TaskFileContent) => {
|
||||||
this.updateTask(taskFileContent);
|
this.updateTask(taskFileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
// boards
|
// boards
|
||||||
createBoard = (name: string): BoardInfoFileContent => {
|
readonly createBoard = (name: string): BoardInfoFileContent => {
|
||||||
const boardInfoFileContent: BoardInfoFileContent =
|
const boardInfoFileContent: BoardInfoFileContent =
|
||||||
BoardsAndTasksModel.createBoardInfoFileContent(
|
BoardsAndTasksModel.createBoardInfoFileContent(
|
||||||
v4(),
|
v4(),
|
||||||
@@ -100,17 +99,17 @@ export default class BoardsAndTasksModel {
|
|||||||
return boardInfoFileContent;
|
return boardInfoFileContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
updateBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
readonly updateBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||||
this.storeBoard(boardInfoFileContent);
|
this.storeBoard(boardInfoFileContent);
|
||||||
this.boardHandlerManager.trigger(boardInfoFileContent);
|
this.boardHandlerManager.trigger(boardInfoFileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateBoardAndSend = (boardInfoFileContent: BoardInfoFileContent): void => {
|
readonly updateBoardAndSend = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||||
this.updateBoard(boardInfoFileContent);
|
this.updateBoard(boardInfoFileContent);
|
||||||
this.chatModel.sendMessage("", undefined, boardInfoFileContent);
|
this.chatModel.sendMessage("", undefined, boardInfoFileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
storeBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
readonly storeBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||||
// store info
|
// store info
|
||||||
this.fileModel.storeFileContent(boardInfoFileContent);
|
this.fileModel.storeFileContent(boardInfoFileContent);
|
||||||
|
|
||||||
@@ -121,7 +120,7 @@ export default class BoardsAndTasksModel {
|
|||||||
this.storageModel.write(boardDirectoryPath, "");
|
this.storageModel.write(boardDirectoryPath, "");
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteBoard = (boardId: string): void => {
|
readonly deleteBoard = (boardId: string): void => {
|
||||||
const boardFilePath: string[] = this.getBoardFilePath(boardId);
|
const boardFilePath: string[] = this.getBoardFilePath(boardId);
|
||||||
const boardDirectoryPath: string[] =
|
const boardDirectoryPath: string[] =
|
||||||
this.getBoardDirectoryPath(boardId);
|
this.getBoardDirectoryPath(boardId);
|
||||||
@@ -130,13 +129,13 @@ export default class BoardsAndTasksModel {
|
|||||||
this.storageModel.removeRecursively(boardDirectoryPath);
|
this.storageModel.removeRecursively(boardDirectoryPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
listBoardIds = (): string[] => {
|
readonly listBoardIds = (): string[] => {
|
||||||
const boardContainerPath: string[] = this.getBoardContainerPath();
|
const boardContainerPath: string[] = this.getBoardContainerPath();
|
||||||
const boardIds: string[] = this.storageModel.list(boardContainerPath);
|
const boardIds: string[] = this.storageModel.list(boardContainerPath);
|
||||||
return boardIds;
|
return boardIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoardInfo = (fileId: string): BoardInfoFileContent | null => {
|
readonly getBoardInfo = (fileId: string): BoardInfoFileContent | null => {
|
||||||
const boardInfoFileContentOrNull: BoardInfoFileContent | null =
|
const boardInfoFileContentOrNull: BoardInfoFileContent | null =
|
||||||
this.fileModel.getLatestFileContent(
|
this.fileModel.getLatestFileContent(
|
||||||
fileId,
|
fileId,
|
||||||
@@ -145,7 +144,7 @@ export default class BoardsAndTasksModel {
|
|||||||
return boardInfoFileContentOrNull;
|
return boardInfoFileContentOrNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
getBoardName = (boardId: string): string => {
|
readonly getBoardName = (boardId: string): string => {
|
||||||
const boardInfo: BoardInfoFileContent | null =
|
const boardInfo: BoardInfoFileContent | null =
|
||||||
this.getBoardInfo(boardId);
|
this.getBoardInfo(boardId);
|
||||||
if (boardInfo == null) return "";
|
if (boardInfo == null) return "";
|
||||||
@@ -153,23 +152,23 @@ export default class BoardsAndTasksModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//tasks
|
//tasks
|
||||||
createTask = (boardId: string): TaskFileContent => {
|
readonly createTask = (boardId: string): TaskFileContent => {
|
||||||
const taskFileContent: TaskFileContent =
|
const taskFileContent: TaskFileContent =
|
||||||
BoardsAndTasksModel.createTaskFileContent(v4(), "", boardId);
|
BoardsAndTasksModel.createTaskFileContent(v4(), "", boardId);
|
||||||
return taskFileContent;
|
return taskFileContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
updateTask = (taskFileContent: TaskFileContent): void => {
|
readonly updateTask = (taskFileContent: TaskFileContent): void => {
|
||||||
this.storeTask(taskFileContent);
|
this.storeTask(taskFileContent);
|
||||||
this.taskHandlerManager.trigger(taskFileContent);
|
this.taskHandlerManager.trigger(taskFileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateTaskAndSend = (taskFileContent: TaskFileContent): void => {
|
readonly updateTaskAndSend = (taskFileContent: TaskFileContent): void => {
|
||||||
this.updateTask(taskFileContent);
|
this.updateTask(taskFileContent);
|
||||||
this.chatModel.sendMessage("", undefined, taskFileContent);
|
this.chatModel.sendMessage("", undefined, taskFileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
storeTask = (taskFileContent: TaskFileContent): void => {
|
readonly storeTask = (taskFileContent: TaskFileContent): void => {
|
||||||
// store info
|
// store info
|
||||||
this.fileModel.storeFileContent(taskFileContent);
|
this.fileModel.storeFileContent(taskFileContent);
|
||||||
|
|
||||||
@@ -184,18 +183,18 @@ export default class BoardsAndTasksModel {
|
|||||||
this.calendarModel.storeTaskReference(taskFileContent);
|
this.calendarModel.storeTaskReference(taskFileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
listTaskIds = (boardId: string): string[] => {
|
readonly listTaskIds = (boardId: string): string[] => {
|
||||||
const taskContainerPath: string[] = this.getTaskContainerPath(boardId);
|
const taskContainerPath: string[] = this.getTaskContainerPath(boardId);
|
||||||
const fileIds: string[] = this.storageModel.list(taskContainerPath);
|
const fileIds: string[] = this.storageModel.list(taskContainerPath);
|
||||||
return fileIds;
|
return fileIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
listTaskVersionIds = (taskId: string): string[] => {
|
readonly listTaskVersionIds = (taskId: string): string[] => {
|
||||||
const versionIds: string[] = this.fileModel.listFileContentIds(taskId);
|
const versionIds: string[] = this.fileModel.listFileContentIds(taskId);
|
||||||
return versionIds;
|
return versionIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
getLatestTaskFileContent = (taskId: string): TaskFileContent | null => {
|
readonly getLatestTaskFileContent = (taskId: string): TaskFileContent | null => {
|
||||||
const taskFileContentOrNull: TaskFileContent | null =
|
const taskFileContentOrNull: TaskFileContent | null =
|
||||||
this.fileModel.getLatestFileContent(
|
this.fileModel.getLatestFileContent(
|
||||||
taskId,
|
taskId,
|
||||||
@@ -204,7 +203,7 @@ export default class BoardsAndTasksModel {
|
|||||||
return taskFileContentOrNull;
|
return taskFileContentOrNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
getSpecificTaskFileContent = (
|
readonly getSpecificTaskFileContent = (
|
||||||
taskId: string,
|
taskId: string,
|
||||||
versionId: string,
|
versionId: string,
|
||||||
): TaskFileContent | null => {
|
): TaskFileContent | null => {
|
||||||
@@ -217,14 +216,14 @@ export default class BoardsAndTasksModel {
|
|||||||
return taskFileContentOrNull;
|
return taskFileContentOrNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteTask = (boardId: string, taskId: string): void => {
|
readonly deleteTask = (boardId: string, taskId: string): void => {
|
||||||
const taskFilePath: string[] = this.getTaskFilePath(taskId);
|
const taskFilePath: string[] = this.getTaskFilePath(taskId);
|
||||||
this.storageModel.removeRecursively(taskFilePath);
|
this.storageModel.removeRecursively(taskFilePath);
|
||||||
|
|
||||||
this.deleteTaskReference(boardId, taskId);
|
this.deleteTaskReference(boardId, taskId);
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteTaskReference = (boardId: string, taskId: string): void => {
|
readonly deleteTaskReference = (boardId: string, taskId: string): void => {
|
||||||
const taskReferencePath: string[] = this.getTaskReferencePath(
|
const taskReferencePath: string[] = this.getTaskReferencePath(
|
||||||
boardId,
|
boardId,
|
||||||
taskId,
|
taskId,
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
// it is responsible for managing calendar-realted reference files for tasks.
|
// cleanup: Phase A
|
||||||
|
|
||||||
import FileModel, { FileModelSubPath } from "./fileModel";
|
import FileModel, { FileModelSubPath } from "./fileModel";
|
||||||
|
|
||||||
import SettingsModel from "../Global/settingsModel";
|
|
||||||
import StorageModel from "../Global/storageModel";
|
|
||||||
import { TaskFileContent } from "./boardsAndTasksModel";
|
import { TaskFileContent } from "./boardsAndTasksModel";
|
||||||
|
import StorageModel from "../Global/storageModel";
|
||||||
|
import SettingsModel from "../Global/settingsModel";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
|
||||||
export default class CalendarModel {
|
export default class CalendarModel {
|
||||||
@@ -13,26 +12,26 @@ export default class CalendarModel {
|
|||||||
readonly settingsModel: SettingsModel;
|
readonly settingsModel: SettingsModel;
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
getBasePath = (): string[] => {
|
get basePath (): string[] {
|
||||||
return this.fileModel.getModelContainerPath(
|
return this.fileModel.getModelContainerPath(
|
||||||
FileModelSubPath.ModelCalendar,
|
FileModelSubPath.ModelCalendar,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getViewPath = (): string[] => {
|
readonly getViewPath = (): string[] => {
|
||||||
return [...this.getBasePath(), FileModelSubPath.ModelView];
|
return [...this.basePath, FileModelSubPath.ModelView];
|
||||||
};
|
};
|
||||||
|
|
||||||
getMonthContainerPath = (): string[] => {
|
readonly getMonthContainerPath = (): string[] => {
|
||||||
return [...this.getBasePath(), CalendarModelSubPaths.Months];
|
return [...this.basePath, CalendarModelSubPaths.Months];
|
||||||
};
|
};
|
||||||
|
|
||||||
getMonthPath = (monthString: string): string[] => {
|
readonly getMonthPath = (monthString: string): string[] => {
|
||||||
return [...this.getMonthContainerPath(), monthString];
|
return [...this.getMonthContainerPath(), monthString];
|
||||||
};
|
};
|
||||||
|
|
||||||
// main
|
// task references
|
||||||
storeTaskReference = (taskFileContent: TaskFileContent): void => {
|
readonly storeTaskReference = (taskFileContent: TaskFileContent): void => {
|
||||||
if (taskFileContent.date == undefined) return;
|
if (taskFileContent.date == undefined) return;
|
||||||
|
|
||||||
const monthString: string = CalendarModel.isoToMonthString(
|
const monthString: string = CalendarModel.isoToMonthString(
|
||||||
@@ -45,19 +44,21 @@ export default class CalendarModel {
|
|||||||
this.storageModel.write(referencePath, "");
|
this.storageModel.write(referencePath, "");
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteTaskReference = (monthString: string, taskId: string): void => {
|
readonly deleteTaskReference = (monthString: string, taskId: string): void => {
|
||||||
const monthPath: string[] = this.getMonthPath(monthString);
|
const monthPath: string[] = this.getMonthPath(monthString);
|
||||||
const referencePath: string[] = [...monthPath, taskId];
|
const referencePath: string[] = [...monthPath, taskId];
|
||||||
|
|
||||||
this.storageModel.write(referencePath, "");
|
this.storageModel.write(referencePath, "");
|
||||||
};
|
};
|
||||||
|
|
||||||
listTaskIds = (monthString: string): string[] => {
|
// data
|
||||||
|
readonly listTaskIds = (monthString: string): string[] => {
|
||||||
const monthPath: string[] = this.getMonthPath(monthString);
|
const monthPath: string[] = this.getMonthPath(monthString);
|
||||||
return this.storageModel.list(monthPath);
|
return this.storageModel.list(monthPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
generateMonthGrid = <T>(
|
// util
|
||||||
|
readonly generateMonthGrid = <T>(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
year: number,
|
year: number,
|
||||||
month: number,
|
month: number,
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
// this file is responsible for managing files within chats.
|
// cleanup: Phase A
|
||||||
|
|
||||||
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
|
import { v4 } from "uuid";
|
||||||
import StorageModel, {
|
import BoardsAndTasksModel from "./boardsAndTasksModel";
|
||||||
StorageModelSubPaths,
|
|
||||||
filePaths,
|
|
||||||
} from "../Global/storageModel";
|
|
||||||
import {
|
import {
|
||||||
StringEntryObject,
|
StringEntryObject,
|
||||||
createTimestamp,
|
createTimestamp,
|
||||||
parseValidObject,
|
parseValidObject,
|
||||||
stringify,
|
stringify,
|
||||||
} from "../Utility/utility";
|
} from "../Utility/utility";
|
||||||
|
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
|
||||||
import BoardsAndTasksModel from "./boardsAndTasksModel";
|
import StorageModel, {
|
||||||
import ChatModel from "../Chat/chatModel";
|
StorageModelSubPaths,
|
||||||
|
filePaths,
|
||||||
|
} from "../Global/storageModel";
|
||||||
import SettingsModel from "../Global/settingsModel";
|
import SettingsModel from "../Global/settingsModel";
|
||||||
import { v4 } from "uuid";
|
import ChatModel from "../Chat/chatModel";
|
||||||
|
|
||||||
export default class FileModel {
|
export default class FileModel {
|
||||||
readonly storageModel: StorageModel;
|
readonly storageModel: StorageModel;
|
||||||
@@ -25,32 +24,32 @@ export default class FileModel {
|
|||||||
readonly boardsAndTasksModel: BoardsAndTasksModel;
|
readonly boardsAndTasksModel: BoardsAndTasksModel;
|
||||||
|
|
||||||
// paths
|
// paths
|
||||||
getBasePath = (): string[] => {
|
get basePath(): string[] {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.Chat,
|
StorageModelSubPaths.Chat,
|
||||||
filePaths.chat.files(this.chatModel.id),
|
filePaths.chat.files(this.chatModel.id),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getFileContainerPath = (): string[] => {
|
readonly getFileContainerPath = (): string[] => {
|
||||||
return [...this.getBasePath(), FileModelSubPath.Data];
|
return [...this.basePath, FileModelSubPath.Data];
|
||||||
};
|
};
|
||||||
|
|
||||||
getModelContainerPath = (modelName: FileModelSubPath): string[] => {
|
readonly getModelContainerPath = (modelName: FileModelSubPath): string[] => {
|
||||||
return [...this.getBasePath(), FileModelSubPath.Model, modelName];
|
return [...this.basePath, FileModelSubPath.Model, modelName];
|
||||||
};
|
};
|
||||||
|
|
||||||
getFilePath = (fileId: string): string[] => {
|
readonly getFilePath = (fileId: string): string[] => {
|
||||||
return [...this.getFileContainerPath(), fileId];
|
return [...this.getFileContainerPath(), fileId];
|
||||||
};
|
};
|
||||||
|
|
||||||
getFileContentPath = (fileId: string, fileContentId: string): string[] => {
|
readonly getFileContentPath = (fileId: string, fileContentId: string): string[] => {
|
||||||
const filePath: string[] = this.getFilePath(fileId);
|
const filePath: string[] = this.getFilePath(fileId);
|
||||||
return [...filePath, fileContentId];
|
return [...filePath, fileContentId];
|
||||||
};
|
};
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
handleStringifiedFileContent = (stringifiedFileContent: string): void => {
|
readonly handleStringifiedFileContent = (stringifiedFileContent: string): void => {
|
||||||
const fileContent: FileContent<string> | null = parseValidObject(
|
const fileContent: FileContent<string> | null = parseValidObject(
|
||||||
stringifiedFileContent,
|
stringifiedFileContent,
|
||||||
FileContentReference,
|
FileContentReference,
|
||||||
@@ -60,7 +59,7 @@ export default class FileModel {
|
|||||||
this.handleFileContent(fileContent);
|
this.handleFileContent(fileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleFileContent = (fileContent: FileContent<string>): void => {
|
readonly handleFileContent = (fileContent: FileContent<string>): void => {
|
||||||
const didStore: boolean = this.storeFileContent(fileContent);
|
const didStore: boolean = this.storeFileContent(fileContent);
|
||||||
if (didStore == false) return;
|
if (didStore == false) return;
|
||||||
|
|
||||||
@@ -69,13 +68,13 @@ export default class FileModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
addFileContentAndSend = (fileContent: FileContent<string>): void => {
|
readonly addFileContentAndSend = (fileContent: FileContent<string>): void => {
|
||||||
this.handleFileContent(fileContent);
|
this.handleFileContent(fileContent);
|
||||||
this.chatModel.sendMessage("", undefined, fileContent);
|
this.chatModel.sendMessage("", undefined, fileContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
// storage
|
// storage
|
||||||
storeFileContent = (fileContent: FileContent<string>): boolean => {
|
readonly storeFileContent = (fileContent: FileContent<string>): boolean => {
|
||||||
const fileContentPath: string[] = this.getFileContentPath(
|
const fileContentPath: string[] = this.getFileContentPath(
|
||||||
fileContent.fileId,
|
fileContent.fileId,
|
||||||
fileContent.fileContentId,
|
fileContent.fileContentId,
|
||||||
@@ -91,22 +90,22 @@ export default class FileModel {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
listFileIds = (): string[] => {
|
readonly listFileIds = (): string[] => {
|
||||||
return this.storageModel.list(this.getBasePath());
|
return this.storageModel.list(this.basePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
listFileContentIds = (fileId: string): string[] => {
|
readonly listFileContentIds = (fileId: string): string[] => {
|
||||||
const filePath: string[] = this.getFilePath(fileId);
|
const filePath: string[] = this.getFilePath(fileId);
|
||||||
return this.storageModel.list(filePath);
|
return this.storageModel.list(filePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
selectLatestFileContentId = (
|
readonly selectLatestFileContentId = (
|
||||||
fileContentIds: string[],
|
fileContentIds: string[],
|
||||||
): string | undefined => {
|
): string | undefined => {
|
||||||
return fileContentIds[fileContentIds.length - 1];
|
return fileContentIds[fileContentIds.length - 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
getFileContent = <T extends FileContent<string>>(
|
readonly getFileContent = <T extends FileContent<string>>(
|
||||||
fileId: string,
|
fileId: string,
|
||||||
fileContentName: string,
|
fileContentName: string,
|
||||||
reference: T,
|
reference: T,
|
||||||
@@ -122,7 +121,7 @@ export default class FileModel {
|
|||||||
return fileContentOrNull;
|
return fileContentOrNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
getLatestFileContent = <T extends FileContent<string>>(
|
readonly getLatestFileContent = <T extends FileContent<string>>(
|
||||||
fileId: string,
|
fileId: string,
|
||||||
reference: T,
|
reference: T,
|
||||||
): T | null => {
|
): T | null => {
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
// this file is responsible for managing UDN connections.
|
// cleanup: Phase A
|
||||||
|
|
||||||
import { ChatMessage, ChatMessageReference } from "../Chat/chatModel";
|
|
||||||
import { HandlerManager, stringify } from "../Utility/utility";
|
|
||||||
import StorageModel, { StorageModelSubPaths, filePaths } from "./storageModel";
|
|
||||||
import UDNFrontend, { Message } from "udn-frontend";
|
import UDNFrontend, { Message } from "udn-frontend";
|
||||||
|
import StorageModel, { StorageModelSubPaths, filePaths } from "./storageModel";
|
||||||
|
import { HandlerManager, stringify } from "../Utility/utility";
|
||||||
|
import { ChatMessage, ChatMessageReference } from "../Chat/chatModel";
|
||||||
|
|
||||||
export default class ConnectionModel {
|
export default class ConnectionModel {
|
||||||
|
// models etc
|
||||||
readonly udn: UDNFrontend;
|
readonly udn: UDNFrontend;
|
||||||
readonly storageModel: StorageModel;
|
readonly storageModel: StorageModel;
|
||||||
|
|
||||||
|
// config
|
||||||
reconnectInterval: number | undefined = undefined;
|
reconnectInterval: number | undefined = undefined;
|
||||||
shouldAttemptReconnect: boolean = false;
|
shouldAttemptReconnect: boolean = false;
|
||||||
|
|
||||||
@@ -20,17 +23,18 @@ export default class ConnectionModel {
|
|||||||
return this.udn.ws?.url;
|
return this.udn.ws?.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handler managers
|
||||||
readonly connectionChangeHandlerManager = new HandlerManager<void>();
|
readonly connectionChangeHandlerManager = new HandlerManager<void>();
|
||||||
readonly messageHandlerManager = new HandlerManager<Message>();
|
readonly messageHandlerManager = new HandlerManager<Message>();
|
||||||
readonly messageSentHandlerManager = new HandlerManager<ChatMessage>();
|
readonly messageSentHandlerManager = new HandlerManager<ChatMessage>();
|
||||||
readonly channelsToSubscribe = new Set<string>();
|
readonly channelsToSubscribe = new Set<string>();
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
handleMessage = (data: Message): void => {
|
readonly handleMessage = (data: Message): void => {
|
||||||
this.messageHandlerManager.trigger(data);
|
this.messageHandlerManager.trigger(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleConnectionChange = (): void => {
|
readonly handleConnectionChange = (): void => {
|
||||||
console.log("connection status:", this.isConnected, this.address);
|
console.log("connection status:", this.isConnected, this.address);
|
||||||
this.connectionChangeHandlerManager.trigger();
|
this.connectionChangeHandlerManager.trigger();
|
||||||
if (this.address == undefined) return;
|
if (this.address == undefined) return;
|
||||||
@@ -41,13 +45,13 @@ export default class ConnectionModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// connection
|
// connection
|
||||||
connect = (address: string): void => {
|
readonly connect = (address: string): void => {
|
||||||
console.log("connecting...", address);
|
console.log("connecting...", address);
|
||||||
this.shouldAttemptReconnect = true;
|
this.shouldAttemptReconnect = true;
|
||||||
this.udn.connect(address);
|
this.udn.connect(address);
|
||||||
};
|
};
|
||||||
|
|
||||||
disconnect = (): void => {
|
readonly disconnect = (): void => {
|
||||||
this.shouldAttemptReconnect = false;
|
this.shouldAttemptReconnect = false;
|
||||||
this.udn.disconnect();
|
this.udn.disconnect();
|
||||||
|
|
||||||
@@ -59,7 +63,7 @@ export default class ConnectionModel {
|
|||||||
this.storageModel.remove(reconnectAddressPath);
|
this.storageModel.remove(reconnectAddressPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
reconnect = (): void => {
|
readonly reconnect = (): void => {
|
||||||
const reconnectAddressPath: string[] = this.getReconnectAddressPath();
|
const reconnectAddressPath: string[] = this.getReconnectAddressPath();
|
||||||
const reconnectAddress: string | null =
|
const reconnectAddress: string | null =
|
||||||
this.storageModel.read(reconnectAddressPath);
|
this.storageModel.read(reconnectAddressPath);
|
||||||
@@ -70,7 +74,7 @@ export default class ConnectionModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// mailbox
|
// mailbox
|
||||||
getMailboxPath = (address: string): string[] => {
|
readonly getMailboxPath = (address: string): string[] => {
|
||||||
const mailboxDirPath = StorageModel.getPath(
|
const mailboxDirPath = StorageModel.getPath(
|
||||||
StorageModelSubPaths.ConnectionModel,
|
StorageModelSubPaths.ConnectionModel,
|
||||||
filePaths.connectionModel.mailboxes,
|
filePaths.connectionModel.mailboxes,
|
||||||
@@ -79,12 +83,12 @@ export default class ConnectionModel {
|
|||||||
return mailboxFilePath;
|
return mailboxFilePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
requestNewMailbox = (): void => {
|
readonly requestNewMailbox = (): void => {
|
||||||
console.log("requesting new mailbox");
|
console.log("requesting new mailbox");
|
||||||
this.udn.requestMailbox();
|
this.udn.requestMailbox();
|
||||||
};
|
};
|
||||||
|
|
||||||
connectMailbox = (): void => {
|
readonly connectMailbox = (): void => {
|
||||||
if (this.address == undefined) return;
|
if (this.address == undefined) return;
|
||||||
|
|
||||||
const mailboxId = this.storageModel.read(
|
const mailboxId = this.storageModel.read(
|
||||||
@@ -96,18 +100,18 @@ export default class ConnectionModel {
|
|||||||
this.udn.connectMailbox(mailboxId);
|
this.udn.connectMailbox(mailboxId);
|
||||||
};
|
};
|
||||||
|
|
||||||
storeMailbox = (mailboxId: string): void => {
|
readonly storeMailbox = (mailboxId: string): void => {
|
||||||
if (this.address == undefined) return;
|
if (this.address == undefined) return;
|
||||||
this.storageModel.write(this.getMailboxPath(this.address), mailboxId);
|
this.storageModel.write(this.getMailboxPath(this.address), mailboxId);
|
||||||
};
|
};
|
||||||
|
|
||||||
// subscription
|
// subscription
|
||||||
addChannel = (channel: string): void => {
|
readonly addChannel = (channel: string): void => {
|
||||||
this.channelsToSubscribe.add(channel);
|
this.channelsToSubscribe.add(channel);
|
||||||
this.sendSubscriptionRequest();
|
this.sendSubscriptionRequest();
|
||||||
};
|
};
|
||||||
|
|
||||||
sendSubscriptionRequest = (): void => {
|
readonly sendSubscriptionRequest = (): void => {
|
||||||
if (this.isConnected == false) return;
|
if (this.isConnected == false) return;
|
||||||
|
|
||||||
for (const channel of this.channelsToSubscribe) {
|
for (const channel of this.channelsToSubscribe) {
|
||||||
@@ -118,14 +122,14 @@ export default class ConnectionModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// outbox
|
// outbox
|
||||||
getOutboxPath = (): string[] => {
|
readonly getOutboxPath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.ConnectionModel,
|
StorageModelSubPaths.ConnectionModel,
|
||||||
filePaths.connectionModel.outbox,
|
filePaths.connectionModel.outbox,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getOutboxMessags = (): ChatMessage[] => {
|
readonly getOutboxMessags = (): ChatMessage[] => {
|
||||||
const outboxPath: string[] = this.getOutboxPath();
|
const outboxPath: string[] = this.getOutboxPath();
|
||||||
const messageIds: string[] = this.storageModel.list(outboxPath);
|
const messageIds: string[] = this.storageModel.list(outboxPath);
|
||||||
|
|
||||||
@@ -144,17 +148,17 @@ export default class ConnectionModel {
|
|||||||
return chatMessages;
|
return chatMessages;
|
||||||
};
|
};
|
||||||
|
|
||||||
addToOutbox = (chatMessage: ChatMessage): void => {
|
readonly addToOutbox = (chatMessage: ChatMessage): void => {
|
||||||
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id];
|
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id];
|
||||||
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
this.storageModel.writeStringifiable(messagePath, chatMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
removeFromOutbox = (chatMessage: ChatMessage): void => {
|
readonly removeFromOutbox = (chatMessage: ChatMessage): void => {
|
||||||
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id];
|
const messagePath: string[] = [...this.getOutboxPath(), chatMessage.id];
|
||||||
this.storageModel.remove(messagePath);
|
this.storageModel.remove(messagePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
sendMessagesInOutbox = (): void => {
|
readonly sendMessagesInOutbox = (): void => {
|
||||||
const messages: ChatMessage[] = this.getOutboxMessags();
|
const messages: ChatMessage[] = this.getOutboxMessags();
|
||||||
|
|
||||||
for (const message of messages) {
|
for (const message of messages) {
|
||||||
@@ -166,14 +170,14 @@ export default class ConnectionModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// messaging
|
// messaging
|
||||||
sendMessageOrStore = (chatMessage: ChatMessage): void => {
|
readonly sendMessageOrStore = (chatMessage: ChatMessage): void => {
|
||||||
const isSent = this.tryToSendMessage(chatMessage);
|
const isSent = this.tryToSendMessage(chatMessage);
|
||||||
if (isSent == true) return;
|
if (isSent == true) return;
|
||||||
|
|
||||||
this.addToOutbox(chatMessage);
|
this.addToOutbox(chatMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
tryToSendMessage = (chatMessage: ChatMessage): boolean => {
|
readonly tryToSendMessage = (chatMessage: ChatMessage): boolean => {
|
||||||
const stringifiedBody: string = stringify(chatMessage);
|
const stringifiedBody: string = stringify(chatMessage);
|
||||||
const isSent: boolean = this.sendPlainMessage(
|
const isSent: boolean = this.sendPlainMessage(
|
||||||
chatMessage.channel,
|
chatMessage.channel,
|
||||||
@@ -183,31 +187,31 @@ export default class ConnectionModel {
|
|||||||
return isSent;
|
return isSent;
|
||||||
};
|
};
|
||||||
|
|
||||||
sendPlainMessage = (channel: string, body: string): boolean => {
|
readonly sendPlainMessage = (channel: string, body: string): boolean => {
|
||||||
return this.udn.sendMessage(channel, body);
|
return this.udn.sendMessage(channel, body);
|
||||||
};
|
};
|
||||||
|
|
||||||
// storage
|
// storage
|
||||||
getPreviousAddressPath = (): string[] => {
|
readonly getPreviousAddressPath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.ConnectionModel,
|
StorageModelSubPaths.ConnectionModel,
|
||||||
filePaths.connectionModel.previousAddresses,
|
filePaths.connectionModel.previousAddresses,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getAddressPath = (address: string): string[] => {
|
readonly getAddressPath = (address: string): string[] => {
|
||||||
const dirPath = this.getPreviousAddressPath();
|
const dirPath = this.getPreviousAddressPath();
|
||||||
return [...dirPath, address];
|
return [...dirPath, address];
|
||||||
};
|
};
|
||||||
|
|
||||||
getReconnectAddressPath = (): string[] => {
|
readonly getReconnectAddressPath = (): string[] => {
|
||||||
return StorageModel.getPath(
|
return StorageModel.getPath(
|
||||||
StorageModelSubPaths.ConnectionModel,
|
StorageModelSubPaths.ConnectionModel,
|
||||||
filePaths.connectionModel.reconnectAddress,
|
filePaths.connectionModel.reconnectAddress,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
storeAddress = (address: string): void => {
|
readonly storeAddress = (address: string): void => {
|
||||||
// history
|
// history
|
||||||
const addressPath = this.getAddressPath(address);
|
const addressPath = this.getAddressPath(address);
|
||||||
this.storageModel.write(addressPath, "");
|
this.storageModel.write(addressPath, "");
|
||||||
@@ -217,7 +221,7 @@ export default class ConnectionModel {
|
|||||||
this.storageModel.write(reconnectAddressPath, address);
|
this.storageModel.write(reconnectAddressPath, address);
|
||||||
};
|
};
|
||||||
|
|
||||||
removeAddress = (address: string): void => {
|
readonly removeAddress = (address: string): void => {
|
||||||
const addressPath = this.getAddressPath(address);
|
const addressPath = this.getAddressPath(address);
|
||||||
this.storageModel.remove(addressPath);
|
this.storageModel.remove(addressPath);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
// this file is responsible for sending and handling files.
|
// cleanup: Phase A
|
||||||
|
|
||||||
|
import { Message } from "udn-frontend";
|
||||||
|
import StorageModel from "./storageModel";
|
||||||
|
import ConnectionModel from "./connectionModel";
|
||||||
import {
|
import {
|
||||||
HandlerManager,
|
HandlerManager,
|
||||||
generateRandomToken,
|
generateRandomToken,
|
||||||
parse,
|
parse,
|
||||||
stringify,
|
stringify,
|
||||||
} from "../Utility/utility";
|
} from "../Utility/utility";
|
||||||
import { decryptString, encryptString } from "../Utility/crypto";
|
|
||||||
|
|
||||||
import ConnectionModel from "./connectionModel";
|
|
||||||
import { Message } from "udn-frontend";
|
|
||||||
import StorageModel from "./storageModel";
|
|
||||||
import { checkMatchesObjectStructure } from "../Utility/typeSafety";
|
import { checkMatchesObjectStructure } from "../Utility/typeSafety";
|
||||||
|
import { decryptString, encryptString } from "../Utility/crypto";
|
||||||
|
|
||||||
export default class FileTransferModel {
|
export default class FileTransferModel {
|
||||||
readonly storageModel: StorageModel;
|
readonly storageModel: StorageModel;
|
||||||
@@ -21,12 +20,14 @@ export default class FileTransferModel {
|
|||||||
|
|
||||||
// data
|
// data
|
||||||
transferData: TransferData | undefined;
|
transferData: TransferData | undefined;
|
||||||
readonly fileHandlerManager = new HandlerManager<string>();
|
|
||||||
readonly readyToSendHandlerManager = new HandlerManager<boolean>();
|
|
||||||
direction: TransferDirections = TransferDirections.Send;
|
direction: TransferDirections = TransferDirections.Send;
|
||||||
|
|
||||||
|
// handler managers
|
||||||
|
readonly fileHandlerManager = new HandlerManager<string>();
|
||||||
|
readonly readyToSendHandlerManager = new HandlerManager<boolean>();
|
||||||
|
|
||||||
// general
|
// general
|
||||||
generateTransferData = (): TransferData => {
|
readonly generateTransferData = (): TransferData => {
|
||||||
const transferData: TransferData = {
|
const transferData: TransferData = {
|
||||||
channel: generateRandomToken(4),
|
channel: generateRandomToken(4),
|
||||||
key: generateRandomToken(6),
|
key: generateRandomToken(6),
|
||||||
@@ -35,12 +36,12 @@ export default class FileTransferModel {
|
|||||||
return transferData;
|
return transferData;
|
||||||
};
|
};
|
||||||
|
|
||||||
prepareToSend = (): void => {
|
readonly prepareToSend = (): void => {
|
||||||
this.direction = TransferDirections.Send;
|
this.direction = TransferDirections.Send;
|
||||||
this.connectionModel.addChannel(this.transferData.channel);
|
this.connectionModel.addChannel(this.transferData.channel);
|
||||||
};
|
};
|
||||||
|
|
||||||
prepareToReceive = (transferData: TransferData): void => {
|
readonly prepareToReceive = (transferData: TransferData): void => {
|
||||||
this.direction = TransferDirections.Receive;
|
this.direction = TransferDirections.Receive;
|
||||||
|
|
||||||
this.connectionModel.addChannel(transferData.channel);
|
this.connectionModel.addChannel(transferData.channel);
|
||||||
@@ -52,7 +53,7 @@ export default class FileTransferModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
handleMessage = (data: Message): void => {
|
readonly handleMessage = (data: Message): void => {
|
||||||
if (this.transferData == undefined) return;
|
if (this.transferData == undefined) return;
|
||||||
if (data.messageChannel != this.transferData.channel) return;
|
if (data.messageChannel != this.transferData.channel) return;
|
||||||
if (
|
if (
|
||||||
@@ -68,7 +69,7 @@ export default class FileTransferModel {
|
|||||||
this.handleFile(data.messageBody);
|
this.handleFile(data.messageBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleFile = async (encryptedFileData: string): Promise<void> => {
|
readonly handleFile = async (encryptedFileData: string): Promise<void> => {
|
||||||
if (this.transferData == undefined) return;
|
if (this.transferData == undefined) return;
|
||||||
|
|
||||||
const decrypted: string = await decryptString(
|
const decrypted: string = await decryptString(
|
||||||
@@ -93,7 +94,7 @@ export default class FileTransferModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// sending
|
// sending
|
||||||
sendFiles = (
|
readonly sendFiles = (
|
||||||
directoryPaths: IteratorObject<string[]>,
|
directoryPaths: IteratorObject<string[]>,
|
||||||
callback: (path: string) => void,
|
callback: (path: string) => void,
|
||||||
): void => {
|
): void => {
|
||||||
@@ -108,7 +109,7 @@ export default class FileTransferModel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sendFile = async (filePath: string[]): Promise<void> => {
|
readonly sendFile = async (filePath: string[]): Promise<void> => {
|
||||||
if (this.transferData == undefined) return;
|
if (this.transferData == undefined) return;
|
||||||
const fileContent: string | null = this.storageModel.read(filePath);
|
const fileContent: string | null = this.storageModel.read(filePath);
|
||||||
if (fileContent == null) return;
|
if (fileContent == null) return;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// this file is responsible for all settings.
|
// cleanup: Phase A
|
||||||
|
|
||||||
import StorageModel, { StorageModelSubPaths, filePaths } from "./storageModel";
|
import StorageModel, { StorageModelSubPaths, filePaths } from "./storageModel";
|
||||||
|
|
||||||
@@ -12,10 +12,10 @@ export default class SettingsModel {
|
|||||||
theme: string;
|
theme: string;
|
||||||
|
|
||||||
// storage
|
// storage
|
||||||
private storeSetting(
|
private readonly storeSetting = (
|
||||||
pathName: keyof typeof filePaths.settingsModel,
|
pathName: keyof typeof filePaths.settingsModel,
|
||||||
value: string,
|
value: string,
|
||||||
): void {
|
): void => {
|
||||||
const path = StorageModel.getPath(
|
const path = StorageModel.getPath(
|
||||||
StorageModelSubPaths.SettingsModel,
|
StorageModelSubPaths.SettingsModel,
|
||||||
filePaths.settingsModel[pathName],
|
filePaths.settingsModel[pathName],
|
||||||
@@ -23,28 +23,28 @@ export default class SettingsModel {
|
|||||||
this.storageModel.write(path, value);
|
this.storageModel.write(path, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
setName = (newValue: string): void => {
|
readonly setName = (newValue: string): void => {
|
||||||
this.username = newValue;
|
this.username = newValue;
|
||||||
this.storeSetting("username", newValue);
|
this.storeSetting("username", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
setFirstDayOfWeek = (newValue: string): void => {
|
readonly setFirstDayOfWeek = (newValue: string): void => {
|
||||||
this.firstDayOfWeek = newValue;
|
this.firstDayOfWeek = newValue;
|
||||||
this.storeSetting("firstDayOfWeek", newValue);
|
this.storeSetting("firstDayOfWeek", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
setLanguage = (newValue: string): void => {
|
readonly setLanguage = (newValue: string): void => {
|
||||||
this.language = newValue;
|
this.language = newValue;
|
||||||
this.storeSetting("language", newValue);
|
this.storeSetting("language", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
setTheme = (newValue: string): void => {
|
readonly setTheme = (newValue: string): void => {
|
||||||
this.theme = newValue;
|
this.theme = newValue;
|
||||||
this.storeSetting("theme", newValue);
|
this.storeSetting("theme", newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
// load
|
// load
|
||||||
private readSetting = (
|
private readonly readSetting = (
|
||||||
pathName: keyof typeof filePaths.settingsModel,
|
pathName: keyof typeof filePaths.settingsModel,
|
||||||
): string => {
|
): string => {
|
||||||
const path = StorageModel.getPath(
|
const path = StorageModel.getPath(
|
||||||
@@ -54,22 +54,22 @@ export default class SettingsModel {
|
|||||||
return this.storageModel.read(path);
|
return this.storageModel.read(path);
|
||||||
};
|
};
|
||||||
|
|
||||||
loadUsername = (): void => {
|
readonly loadUsername = (): void => {
|
||||||
const content: string | null = this.readSetting("username");
|
const content: string | null = this.readSetting("username");
|
||||||
this.username = content ?? "";
|
this.username = content ?? "";
|
||||||
};
|
};
|
||||||
|
|
||||||
loadFirstDayofWeek = (): void => {
|
readonly loadFirstDayofWeek = (): void => {
|
||||||
const content: string | null = this.readSetting("firstDayOfWeek");
|
const content: string | null = this.readSetting("firstDayOfWeek");
|
||||||
this.firstDayOfWeek = content ?? "0";
|
this.firstDayOfWeek = content ?? "0";
|
||||||
};
|
};
|
||||||
|
|
||||||
loadLanguage = (): void => {
|
readonly loadLanguage = (): void => {
|
||||||
const content: string | null = this.readSetting("language");
|
const content: string | null = this.readSetting("language");
|
||||||
this.language = content ?? SettingsModel.getSystemLanguage();
|
this.language = content ?? SettingsModel.getSystemLanguage();
|
||||||
};
|
};
|
||||||
|
|
||||||
loadTheme = (): void => {
|
readonly loadTheme = (): void => {
|
||||||
const content: string | null = this.readSetting("theme");
|
const content: string | null = this.readSetting("theme");
|
||||||
this.theme = content ?? ThemeSettings.System;
|
this.theme = content ?? ThemeSettings.System;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// this file is responsible for reading and writing persistent data.
|
// cleanup: Phase A
|
||||||
|
|
||||||
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
|
|
||||||
import { localeCompare, parseValidObject, stringify } from "../Utility/utility";
|
import { localeCompare, parseValidObject, stringify } from "../Utility/utility";
|
||||||
|
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
|
||||||
|
|
||||||
export const PATH_COMPONENT_SEPARATOR = "\\";
|
export const PATH_COMPONENT_SEPARATOR = "\\";
|
||||||
|
|
||||||
@@ -9,14 +9,14 @@ export default class StorageModel {
|
|||||||
storageEntryTree: StorageEntry = {};
|
storageEntryTree: StorageEntry = {};
|
||||||
|
|
||||||
// read
|
// read
|
||||||
read = (pathComponents: string[]): string | null => {
|
readonly read = (pathComponents: string[]): string | null => {
|
||||||
const pathString: string = StorageModel.pathComponentsToString(
|
const pathString: string = StorageModel.pathComponentsToString(
|
||||||
...pathComponents,
|
...pathComponents,
|
||||||
);
|
);
|
||||||
return localStorage.getItem(pathString);
|
return localStorage.getItem(pathString);
|
||||||
};
|
};
|
||||||
|
|
||||||
list = (pathComponents: string[]): string[] => {
|
readonly list = (pathComponents: string[]): string[] => {
|
||||||
let currentParent: StorageEntry = this.storageEntryTree;
|
let currentParent: StorageEntry = this.storageEntryTree;
|
||||||
for (const component of pathComponents) {
|
for (const component of pathComponents) {
|
||||||
const nextParent: StorageEntry | undefined =
|
const nextParent: StorageEntry | undefined =
|
||||||
@@ -29,7 +29,7 @@ export default class StorageModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// write
|
// write
|
||||||
write = (pathComponents: string[], value: string): void => {
|
readonly write = (pathComponents: string[], value: string): void => {
|
||||||
const pathString: string = StorageModel.pathComponentsToString(
|
const pathString: string = StorageModel.pathComponentsToString(
|
||||||
...pathComponents,
|
...pathComponents,
|
||||||
);
|
);
|
||||||
@@ -37,7 +37,7 @@ export default class StorageModel {
|
|||||||
this.updateTree(...pathComponents);
|
this.updateTree(...pathComponents);
|
||||||
};
|
};
|
||||||
|
|
||||||
remove = (
|
readonly remove = (
|
||||||
pathComponents: string[],
|
pathComponents: string[],
|
||||||
shouldInitialize: boolean = true,
|
shouldInitialize: boolean = true,
|
||||||
): void => {
|
): void => {
|
||||||
@@ -51,7 +51,7 @@ export default class StorageModel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rename = (
|
readonly rename = (
|
||||||
sourcePathComponents: string[],
|
sourcePathComponents: string[],
|
||||||
destinationPathComponents: string[],
|
destinationPathComponents: string[],
|
||||||
shouldInitialize: boolean = true,
|
shouldInitialize: boolean = true,
|
||||||
@@ -69,7 +69,7 @@ export default class StorageModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// recursion
|
// recursion
|
||||||
recurse = (rootDirectory: string[], fn: (path: string[]) => void): void => {
|
readonly recurse = (rootDirectory: string[], fn: (path: string[]) => void): void => {
|
||||||
loop_over_files: for (const key of Object.keys(localStorage)) {
|
loop_over_files: for (const key of Object.keys(localStorage)) {
|
||||||
// get path of current entity
|
// get path of current entity
|
||||||
const pathComponentsOfCurrentEntity: string[] =
|
const pathComponentsOfCurrentEntity: string[] =
|
||||||
@@ -92,14 +92,14 @@ export default class StorageModel {
|
|||||||
this.initializeTree();
|
this.initializeTree();
|
||||||
};
|
};
|
||||||
|
|
||||||
removeRecursively = (pathComponents: string[]): void => {
|
readonly removeRecursively = (pathComponents: string[]): void => {
|
||||||
this.recurse(pathComponents, (path: string[]) =>
|
this.recurse(pathComponents, (path: string[]) =>
|
||||||
this.remove(path, false),
|
this.remove(path, false),
|
||||||
);
|
);
|
||||||
this.initializeTree();
|
this.initializeTree();
|
||||||
};
|
};
|
||||||
|
|
||||||
renameRecursively = (
|
readonly renameRecursively = (
|
||||||
sourcePathComponents: string[],
|
sourcePathComponents: string[],
|
||||||
destinationPathComponents: string[],
|
destinationPathComponents: string[],
|
||||||
): void => {
|
): void => {
|
||||||
@@ -120,7 +120,7 @@ export default class StorageModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// stringifiable
|
// stringifiable
|
||||||
writeStringifiable = (
|
readonly writeStringifiable = (
|
||||||
pathComponents: string[],
|
pathComponents: string[],
|
||||||
value: ValidObject,
|
value: ValidObject,
|
||||||
): void => {
|
): void => {
|
||||||
@@ -128,7 +128,7 @@ export default class StorageModel {
|
|||||||
this.write(pathComponents, valueString);
|
this.write(pathComponents, valueString);
|
||||||
};
|
};
|
||||||
|
|
||||||
readStringifiable = <T extends ValidObject>(
|
readonly readStringifiable = <T extends ValidObject>(
|
||||||
pathComponents: string[],
|
pathComponents: string[],
|
||||||
reference: T,
|
reference: T,
|
||||||
): T | null => {
|
): T | null => {
|
||||||
@@ -142,7 +142,7 @@ export default class StorageModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// cleaning
|
// cleaning
|
||||||
removeJunk = (): void => {
|
readonly removeJunk = (): void => {
|
||||||
this.recurse([], (path: string[]) => {
|
this.recurse([], (path: string[]) => {
|
||||||
if (path[0] == DATA_VERSION) return;
|
if (path[0] == DATA_VERSION) return;
|
||||||
this.remove(path);
|
this.remove(path);
|
||||||
@@ -150,7 +150,7 @@ export default class StorageModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// tree
|
// tree
|
||||||
initializeTree = (): void => {
|
readonly initializeTree = (): void => {
|
||||||
console.log("initializing tree");
|
console.log("initializing tree");
|
||||||
|
|
||||||
this.storageEntryTree = {};
|
this.storageEntryTree = {};
|
||||||
@@ -161,7 +161,7 @@ export default class StorageModel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
updateTree = (...pathComponents: string[]): void => {
|
readonly updateTree = (...pathComponents: string[]): void => {
|
||||||
let currentParent: StorageEntry = this.storageEntryTree;
|
let currentParent: StorageEntry = this.storageEntryTree;
|
||||||
for (const pathPart of pathComponents) {
|
for (const pathPart of pathComponents) {
|
||||||
if (!currentParent[pathPart]) {
|
if (!currentParent[pathPart]) {
|
||||||
@@ -172,7 +172,7 @@ export default class StorageModel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
printTree = (): string => {
|
readonly printTree = (): string => {
|
||||||
return stringify(this.storageEntryTree);
|
return stringify(this.storageEntryTree);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -36,15 +36,15 @@ export async function decryptString(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// process
|
// process
|
||||||
export function encode(string: string): Uint8Array {
|
function encode(string: string): Uint8Array {
|
||||||
return new TextEncoder().encode(string);
|
return new TextEncoder().encode(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decode(array: Uint8Array): string {
|
function decode(array: Uint8Array): string {
|
||||||
return new TextDecoder("utf-8").decode(array);
|
return new TextDecoder("utf-8").decode(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function encrypt(
|
async function encrypt(
|
||||||
iv: Uint8Array,
|
iv: Uint8Array,
|
||||||
key: CryptoKey,
|
key: CryptoKey,
|
||||||
message: string,
|
message: string,
|
||||||
@@ -57,7 +57,7 @@ export async function encrypt(
|
|||||||
return new Uint8Array(arrayBuffer);
|
return new Uint8Array(arrayBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function decrypt(
|
async function decrypt(
|
||||||
iv: Uint8Array,
|
iv: Uint8Array,
|
||||||
key: CryptoKey,
|
key: CryptoKey,
|
||||||
cyphertext: Uint8Array,
|
cyphertext: Uint8Array,
|
||||||
@@ -70,16 +70,16 @@ export async function decrypt(
|
|||||||
return arrayBufferToString(arrayBuffer);
|
return arrayBufferToString(arrayBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function hash(encoded: Uint8Array): Promise<ArrayBuffer> {
|
async function hash(encoded: Uint8Array): Promise<ArrayBuffer> {
|
||||||
return await crypto.subtle.digest("SHA-256", encoded);
|
return await crypto.subtle.digest("SHA-256", encoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
// iv
|
// iv
|
||||||
export function generateIV(): Uint8Array {
|
function generateIV(): Uint8Array {
|
||||||
return crypto.getRandomValues(new Uint8Array(IV_SIZE));
|
return crypto.getRandomValues(new Uint8Array(IV_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function splitMergedString(mergedString: string): [Uint8Array, string] {
|
function splitMergedString(mergedString: string): [Uint8Array, string] {
|
||||||
const iv = mergedString.slice(0, IV_SIZE);
|
const iv = mergedString.slice(0, IV_SIZE);
|
||||||
const encryptedString = mergedString.slice(IV_SIZE);
|
const encryptedString = mergedString.slice(IV_SIZE);
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ export function splitMergedString(mergedString: string): [Uint8Array, string] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// key
|
// key
|
||||||
export async function importKey(
|
async function importKey(
|
||||||
passphrase: string,
|
passphrase: string,
|
||||||
purpose: "encrypt" | "decrypt",
|
purpose: "encrypt" | "decrypt",
|
||||||
): Promise<CryptoKey> {
|
): Promise<CryptoKey> {
|
||||||
@@ -101,15 +101,15 @@ export async function importKey(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// conversion
|
// conversion
|
||||||
export function arrayBufferToString(arrayBuffer: ArrayBuffer): string {
|
function arrayBufferToString(arrayBuffer: ArrayBuffer): string {
|
||||||
const uInt8Array = new Uint8Array(arrayBuffer);
|
const uInt8Array = new Uint8Array(arrayBuffer);
|
||||||
return decode(uInt8Array);
|
return decode(uInt8Array);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function uInt8ToArray(uInt8Array: Uint8Array): number[] {
|
function uInt8ToArray(uInt8Array: Uint8Array): number[] {
|
||||||
return Array.from(uInt8Array);
|
return Array.from(uInt8Array);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function arrayToUint8(array: number[]): Uint8Array {
|
function arrayToUint8(array: number[]): Uint8Array {
|
||||||
return new Uint8Array(array);
|
return new Uint8Array(array);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-10
@@ -1,5 +1,14 @@
|
|||||||
// this file is responsible for migrating data from v1 to v2.
|
// this file is responsible for migrating data from v1 to v2.
|
||||||
|
|
||||||
|
import { v4 } from "uuid";
|
||||||
|
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
||||||
|
import {
|
||||||
|
getLocalStorageItemAndClear,
|
||||||
|
parseArray,
|
||||||
|
parseOrFallback,
|
||||||
|
} from "../Model/Utility/utility";
|
||||||
|
import { checkMatchesObjectStructure } from "../Model/Utility/typeSafety";
|
||||||
|
import FileModel from "../Model/Files/fileModel";
|
||||||
import {
|
import {
|
||||||
BoardInfoFileContent,
|
BoardInfoFileContent,
|
||||||
TaskFileContent,
|
TaskFileContent,
|
||||||
@@ -8,16 +17,6 @@ import ChatModel, {
|
|||||||
ChatMessage,
|
ChatMessage,
|
||||||
ChatMessageStatuses,
|
ChatMessageStatuses,
|
||||||
} from "../Model/Chat/chatModel";
|
} from "../Model/Chat/chatModel";
|
||||||
import {
|
|
||||||
getLocalStorageItemAndClear,
|
|
||||||
parseArray,
|
|
||||||
parseOrFallback,
|
|
||||||
} from "../Model/Utility/utility";
|
|
||||||
|
|
||||||
import FileModel from "../Model/Files/fileModel";
|
|
||||||
import { checkMatchesObjectStructure } from "../Model/Utility/typeSafety";
|
|
||||||
import { v4 } from "uuid";
|
|
||||||
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
|
||||||
|
|
||||||
export default class v1Upgrader {
|
export default class v1Upgrader {
|
||||||
// general
|
// general
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { ViewController } from "../viewController";
|
||||||
|
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
||||||
import {
|
import {
|
||||||
PropertyValueList,
|
PropertyValueList,
|
||||||
createPropertyValueIndexState,
|
createPropertyValueIndexState,
|
||||||
} from "../Components/propertyValueList";
|
} from "../Components/propertyValueList";
|
||||||
|
|
||||||
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
|
||||||
import { FilteredList } from "../Components/filteredList";
|
import { FilteredList } from "../Components/filteredList";
|
||||||
import { TaskCategoryBulkChangeViewModel } from "../../ViewModel/Utility/taskPropertyBulkChangeViewModel";
|
import { TaskCategoryBulkChangeViewModel } from "../../ViewModel/Utility/taskPropertyBulkChangeViewModel";
|
||||||
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
||||||
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import { ViewController } from "../viewController";
|
|
||||||
|
|
||||||
export function BoardKanbanPage(
|
export function BoardKanbanPage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { BoardStatusGridPage } from "./boardStatusGridPage";
|
||||||
|
import { BoardKanbanPage } from "./boardKanbanPage";
|
||||||
|
import { ViewController } from "../viewController";
|
||||||
|
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
|
||||||
|
import { SearchModal } from "../Modals/searchModal";
|
||||||
|
import { BoardSettingsModal } from "../Modals/boardSettingsModal";
|
||||||
|
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
||||||
|
import { BoardViewToggleButton } from "../Components/boardViewToggleButton";
|
||||||
import BoardViewModel, {
|
import BoardViewModel, {
|
||||||
BoardPageTypes,
|
BoardPageTypes,
|
||||||
} from "../../ViewModel/Pages/boardViewModel";
|
} from "../../ViewModel/Pages/boardViewModel";
|
||||||
|
|
||||||
import { BoardKanbanPage } from "./boardKanbanPage";
|
|
||||||
import { BoardSettingsModal } from "../Modals/boardSettingsModal";
|
|
||||||
import { BoardStatusGridPage } from "./boardStatusGridPage";
|
|
||||||
import { BoardViewToggleButton } from "../Components/boardViewToggleButton";
|
|
||||||
import { SearchModal } from "../Modals/searchModal";
|
|
||||||
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
|
|
||||||
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import { ViewController } from "../viewController";
|
|
||||||
|
|
||||||
export function BoardPage(
|
export function BoardPage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { ViewController } from "../viewController";
|
||||||
|
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
||||||
import {
|
import {
|
||||||
PropertyValueList,
|
PropertyValueList,
|
||||||
collectPropertyValuesToState,
|
collectPropertyValuesToState,
|
||||||
createPropertyValueIndexState,
|
createPropertyValueIndexState,
|
||||||
createSortedPropertyValueState,
|
createSortedPropertyValueState,
|
||||||
} from "../Components/propertyValueList";
|
} from "../Components/propertyValueList";
|
||||||
|
import { FilteredList } from "../Components/filteredList";
|
||||||
import {
|
import {
|
||||||
TaskCategoryBulkChangeViewModel,
|
TaskCategoryBulkChangeViewModel,
|
||||||
TaskStatusBulkChangeViewModel,
|
TaskStatusBulkChangeViewModel,
|
||||||
} from "../../ViewModel/Utility/taskPropertyBulkChangeViewModel";
|
} from "../../ViewModel/Utility/taskPropertyBulkChangeViewModel";
|
||||||
|
|
||||||
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
|
||||||
import { FilteredList } from "../Components/filteredList";
|
|
||||||
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
||||||
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import { ViewController } from "../viewController";
|
|
||||||
|
|
||||||
export function BoardStatusGridPage(
|
export function BoardStatusGridPage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import "./calendarPage.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import "./calendarPage.css";
|
||||||
import CalendarPageViewModel from "../../ViewModel/Pages/calendarPageViewModel";
|
import { ViewController } from "../viewController";
|
||||||
import { MonthGrid } from "../Components/monthGrid";
|
|
||||||
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
|
import { TaskSettingsModal } from "../Modals/taskSettingsModal";
|
||||||
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
import { TaskViewModelToEntry } from "../Components/taskEntry";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import { PlaceholderView } from "../Components/placeholderView";
|
import { PlaceholderView } from "../Components/placeholderView";
|
||||||
import { ViewController } from "../viewController";
|
import { MonthGrid } from "../Components/monthGrid";
|
||||||
|
import CalendarPageViewModel from "../../ViewModel/Pages/calendarPageViewModel";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
|
||||||
export function CalendarPage(
|
export function CalendarPage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import "./messagePage.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import "./messagePage.css";
|
||||||
|
import { ViewController } from "../viewController";
|
||||||
|
import { MessageFilterModal } from "../Modals/messageFilterModal";
|
||||||
|
import { ReplyPreview } from "../Components/replyPreview";
|
||||||
|
import { ChatMessage } from "../Components/chatMessage";
|
||||||
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
import { ChatMessage } from "../Components/chatMessage";
|
|
||||||
import { MessageFilterModal } from "../Modals/messageFilterModal";
|
|
||||||
import { ViewController } from "../viewController";
|
|
||||||
import { ReplyPreview } from "../Components/replyPreview";
|
|
||||||
|
|
||||||
export function MessagePage(
|
export function MessagePage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Colors } from "../../colors";
|
|
||||||
import { ColorPicker } from "../Components/colorPicker";
|
|
||||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
|
||||||
import { DeletableListItem } from "../Components/deletableListItem";
|
import { DeletableListItem } from "../Components/deletableListItem";
|
||||||
|
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||||
|
import { ColorPicker } from "../Components/colorPicker";
|
||||||
import SettingsPageViewModel from "../../ViewModel/Pages/settingsPageViewModel";
|
import SettingsPageViewModel from "../../ViewModel/Pages/settingsPageViewModel";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
import "./taskPage.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import "./taskPage.css";
|
||||||
import { BoardPage } from "./boardPage";
|
import { BoardPage } from "./boardPage";
|
||||||
|
import { ViewController } from "../viewController";
|
||||||
|
import { PlaceholderView } from "../Components/placeholderView";
|
||||||
import { BoardViewModelToEntry } from "../Components/boardEntry";
|
import { BoardViewModelToEntry } from "../Components/boardEntry";
|
||||||
import TaskPageViewModel from "../../ViewModel/Pages/taskPageViewModel";
|
import TaskPageViewModel from "../../ViewModel/Pages/taskPageViewModel";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import { PlaceholderView } from "../Components/placeholderView";
|
|
||||||
import { v4 } from "uuid";
|
|
||||||
import { ViewController } from "../viewController";
|
|
||||||
|
|
||||||
export function TaskPage(
|
export function TaskPage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
|
||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
|
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
||||||
|
|
||||||
export function BoardEntry(boardViewModel: BoardViewModel) {
|
export function BoardEntry(boardViewModel: BoardViewModel) {
|
||||||
const view = (
|
const view = (
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { RibbonButton } from "./ribbonButton";
|
||||||
import BoardViewModel, {
|
import BoardViewModel, {
|
||||||
BoardPageTypes,
|
BoardPageTypes,
|
||||||
} from "../../ViewModel/Pages/boardViewModel";
|
} from "../../ViewModel/Pages/boardViewModel";
|
||||||
|
|
||||||
import { RibbonButton } from "./ribbonButton";
|
|
||||||
|
|
||||||
export function BoardViewToggleButton(
|
export function BoardViewToggleButton(
|
||||||
label: string,
|
label: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ChatViewModel from "../../ViewModel/Chat/chatViewModel";
|
import ChatViewModel from "../../ViewModel/Chat/chatViewModel";
|
||||||
|
|
||||||
export function ChatEntry(chatViewModel: ChatViewModel) {
|
export function ChatEntry(chatViewModel: ChatViewModel) {
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { ChatMessageInfoModal } from "../Modals/chatMessageInfoModal";
|
|
||||||
import { ChatMessageStatuses } from "../../Model/Chat/chatModel";
|
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import { MessageReactionButtonRow } from "./messageReactionButtonRow";
|
import { MessageReactionButtonRow } from "./messageReactionButtonRow";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import { InlineReply } from "./inlineReply";
|
import { InlineReply } from "./inlineReply";
|
||||||
import { ViewController } from "../viewController";
|
import { ChatMessageInfoModal } from "../Modals/chatMessageInfoModal";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
|
import { ChatMessageStatuses } from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export function ChatMessage(
|
export function ChatMessage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { RibbonButton } from "./ribbonButton";
|
||||||
import ChatViewModel, {
|
import ChatViewModel, {
|
||||||
ChatPageTypes,
|
ChatPageTypes,
|
||||||
} from "../../ViewModel/Chat/chatViewModel";
|
} from "../../ViewModel/Chat/chatViewModel";
|
||||||
|
|
||||||
import { RibbonButton } from "./ribbonButton";
|
|
||||||
|
|
||||||
export function ChatViewToggleButton(
|
export function ChatViewToggleButton(
|
||||||
label: string,
|
label: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Colors } from "../../colors";
|
import { Colors } from "../../colors";
|
||||||
|
|
||||||
export function ColorPicker(selectedColor: React.State<Colors>) {
|
export function ColorPicker(selectedColor: React.State<Colors>) {
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
||||||
import StorageModel, {
|
import StorageModel, {
|
||||||
PATH_COMPONENT_SEPARATOR,
|
PATH_COMPONENT_SEPARATOR,
|
||||||
} from "../../Model/Global/storageModel";
|
} from "../../Model/Global/storageModel";
|
||||||
|
|
||||||
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
|
||||||
|
|
||||||
export function DirectoryItemList(
|
export function DirectoryItemList(
|
||||||
storageViewModel: StorageViewModel,
|
storageViewModel: StorageViewModel,
|
||||||
pathString: string = PATH_COMPONENT_SEPARATOR,
|
pathString: string = PATH_COMPONENT_SEPARATOR,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
StringEntryObject,
|
StringEntryObject,
|
||||||
checkDoesObjectMatchReference,
|
checkDoesObjectMatchReference,
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
|
|
||||||
export function InlineReply(chatMessageViewModel: ChatMessageViewModel) {
|
export function InlineReply(chatMessageViewModel: ChatMessageViewModel) {
|
||||||
const reply = chatMessageViewModel.inlineReply;
|
const reply = chatMessageViewModel.inlineReply;
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
import {
|
|
||||||
ChatMessageReaction,
|
|
||||||
ReactionSymbols,
|
|
||||||
} from "../../Model/Chat/chatModel";
|
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
|
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export function MessageReactionButton(
|
export function MessageReactionButton(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import { MessageReactionButton } from "./messageReactionButton";
|
import { MessageReactionButton } from "./messageReactionButton";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
|
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export function MessageReactionButtonRow(
|
export function MessageReactionButtonRow(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import { ChatMessageReaction } from "../../Model/Chat/chatModel";
|
import { ChatMessageReaction } from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export function MessageReactionEntry(reaction: ChatMessageReaction) {
|
export function MessageReactionEntry(reaction: ChatMessageReaction) {
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
import {
|
|
||||||
ChatMessageReaction,
|
|
||||||
ReactionSymbols,
|
|
||||||
} from "../../Model/Chat/chatModel";
|
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
||||||
|
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export function MessageReactionFilterButton(
|
export function MessageReactionFilterButton(
|
||||||
messagePageViewModel: MessagePageViewModel,
|
messagePageViewModel: MessagePageViewModel,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import "./monthGrid.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
import { MonthGrid } from "../../Model/Files/calendarModel";
|
import "./monthGrid.css";
|
||||||
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
|
||||||
import { localeCompare } from "../../Model/Utility/utility";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
|
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import { localeCompare } from "../../Model/Utility/utility";
|
||||||
|
import { MonthGrid } from "../../Model/Files/calendarModel";
|
||||||
|
|
||||||
export function MonthGrid<T>(
|
export function MonthGrid<T>(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
@@ -69,7 +68,9 @@ export function MonthGrid<T>(
|
|||||||
return (
|
return (
|
||||||
monthGrid.isCurrentMonth == true &&
|
monthGrid.isCurrentMonth == true &&
|
||||||
date ==
|
date ==
|
||||||
coreViewModel.unwrappedTodayDate.getDate().toString()
|
coreViewModel.unwrappedTodayDate
|
||||||
|
.getDate()
|
||||||
|
.toString()
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
StringEntryObject,
|
StringEntryObject,
|
||||||
collectObjectValuesForKey,
|
collectObjectValuesForKey,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
|
|
||||||
export function ReplyPreview(
|
export function ReplyPreview(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import BoardViewModel, {
|
|
||||||
BoardPageTypes,
|
|
||||||
} from "../../ViewModel/Pages/boardViewModel";
|
|
||||||
|
|
||||||
export function RibbonButton(
|
export function RibbonButton(
|
||||||
label: string,
|
label: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
||||||
|
|
||||||
export function TaskEntry(taskViewModel: TaskViewModel) {
|
export function TaskEntry(taskViewModel: TaskViewModel) {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
|
||||||
import { ColorPicker } from "../Components/colorPicker";
|
|
||||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
|
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||||
|
import { ColorPicker } from "../Components/colorPicker";
|
||||||
|
import BoardViewModel from "../../ViewModel/Pages/boardViewModel";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
|
||||||
export function BoardSettingsModal(
|
export function BoardSettingsModal(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { MessageReactionEntry } from "../Components/messageReactionEntry";
|
||||||
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
|
||||||
import { MessageReactionButtonRow } from "../Components/messageReactionButtonRow";
|
import { MessageReactionButtonRow } from "../Components/messageReactionButtonRow";
|
||||||
import { InfoTile } from "../Components/infoTile";
|
import { InfoTile } from "../Components/infoTile";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import { MessageReactionEntry } from "../Components/messageReactionEntry";
|
import ChatMessageViewModel from "../../ViewModel/Chat/chatMessageViewModel";
|
||||||
|
|
||||||
export function ChatMessageInfoModal(
|
export function ChatMessageInfoModal(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ConnectionViewModel from "../../ViewModel/Global/connectionViewModel";
|
|
||||||
import { DeletableListItem } from "../Components/deletableListItem";
|
import { DeletableListItem } from "../Components/deletableListItem";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import ConnectionViewModel from "../../ViewModel/Global/connectionViewModel";
|
||||||
|
|
||||||
export function ConnectionModal(
|
export function ConnectionModal(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { ViewController } from "../viewController";
|
||||||
|
import { StringToTextSpan } from "../Components/textSpan";
|
||||||
import FileTransferViewModel, {
|
import FileTransferViewModel, {
|
||||||
FileTransferModals,
|
FileTransferModals,
|
||||||
FileTransferOption,
|
FileTransferOption,
|
||||||
} from "../../ViewModel/Global/fileTransferViewModel";
|
} from "../../ViewModel/Global/fileTransferViewModel";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import ConnectionViewModel from "../../ViewModel/Global/connectionViewModel";
|
import ConnectionViewModel from "../../ViewModel/Global/connectionViewModel";
|
||||||
import StorageModel from "../../Model/Global/storageModel";
|
import StorageModel from "../../Model/Global/storageModel";
|
||||||
import { StringToTextSpan } from "../Components/textSpan";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import { ViewController } from "../viewController";
|
|
||||||
|
|
||||||
export function DataTransferModalWrapper(
|
export function DataTransferModalWrapper(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
|
||||||
import { MessageReactionFilterButton } from "../Components/messageReactionFilterButton";
|
|
||||||
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
|
||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
|
import { MessageReactionFilterButton } from "../Components/messageReactionFilterButton";
|
||||||
|
import MessagePageViewModel from "../../ViewModel/Pages/messagePageViewModel";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import { ReactionSymbols } from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export function MessageFilterModal<T>(
|
export function MessageFilterModal<T>(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import * as React from "bloatless-react";
|
|
||||||
|
|
||||||
import SearchViewModel from "../../ViewModel/Utility/searchViewModel";
|
|
||||||
import { StringToOption } from "../Components/option";
|
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import * as React from "bloatless-react";
|
||||||
import { ViewController } from "../viewController";
|
import { ViewController } from "../viewController";
|
||||||
|
import { StringToOption } from "../Components/option";
|
||||||
|
import SearchViewModel from "../../ViewModel/Utility/searchViewModel";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
|
||||||
export function SearchModal<T>(
|
export function SearchModal<T>(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import { SplitModal } from "./splitModal";
|
||||||
import { languageNames } from "../translations";
|
import { languageNames } from "../translations";
|
||||||
|
import { PlaceholderView } from "../Components/placeholderView";
|
||||||
|
import { OptionButtonList } from "../Components/optionButtonList";
|
||||||
|
import { NavigationButton } from "../Components/navigationButton";
|
||||||
|
import { InfoTile } from "../Components/infoTile";
|
||||||
import SettingsViewModel, {
|
import SettingsViewModel, {
|
||||||
SettingsModalPages,
|
SettingsModalPages,
|
||||||
} from "../../ViewModel/Global/settingsViewModel";
|
} from "../../ViewModel/Global/settingsViewModel";
|
||||||
import { SplitModal } from "./splitModal";
|
|
||||||
import { InfoTile } from "../Components/infoTile";
|
|
||||||
import { Option } from "../Components/option";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
import { Languages, ThemeSettings } from "../../Model/Global/settingsModel";
|
import { Languages, ThemeSettings } from "../../Model/Global/settingsModel";
|
||||||
import { OptionButtonList } from "../Components/optionButtonList";
|
|
||||||
import { stringify } from "../../Model/Utility/utility";
|
|
||||||
import { PlaceholderView } from "../Components/placeholderView";
|
|
||||||
import { NavigationButton } from "../Components/navigationButton";
|
|
||||||
|
|
||||||
export function SettingsModal(
|
export function SettingsModal(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
|
||||||
import "./splitModal.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import "./splitModal.css";
|
||||||
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
|
||||||
export function SplitModal<T>(
|
export function SplitModal<T>(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { PATH_COMPONENT_SEPARATOR } from "../../Model/Global/storageModel";
|
|
||||||
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
|
||||||
|
|
||||||
import { SplitModal } from "./splitModal";
|
import { SplitModal } from "./splitModal";
|
||||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
|
||||||
import { DirectoryItemList } from "../Components/directoryItemList";
|
import { DirectoryItemList } from "../Components/directoryItemList";
|
||||||
|
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||||
|
import StorageViewModel from "../../ViewModel/Global/storageViewModel";
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
import { PATH_COMPONENT_SEPARATOR } from "../../Model/Global/storageModel";
|
||||||
|
|
||||||
export function StorageModal(
|
export function StorageModal(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
|
import { v4 } from "uuid";
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Entry,
|
Entry,
|
||||||
Option,
|
Option,
|
||||||
StringToOption,
|
StringToOption,
|
||||||
VersionIdToOption,
|
VersionIdToOption,
|
||||||
} from "../Components/option";
|
} from "../Components/option";
|
||||||
|
|
||||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||||
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
||||||
import { v4 } from "uuid";
|
|
||||||
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../../ViewModel/Global/coreViewModel";
|
||||||
|
|
||||||
export function TaskSettingsModal(
|
export function TaskSettingsModal(
|
||||||
|
|||||||
+8
-11
@@ -1,16 +1,13 @@
|
|||||||
import "./homePage.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ChatViewModel, { ChatPageTypes } from "../ViewModel/Chat/chatViewModel";
|
|
||||||
|
|
||||||
import { CalendarPage } from "./ChatPages/calendarPage";
|
|
||||||
import { ChatViewToggleButton } from "./Components/chatViewToggleButton";
|
|
||||||
import { MessagePage } from "./ChatPages/messagePage";
|
|
||||||
import { SettingsPage } from "./ChatPages/settingsPage";
|
|
||||||
import { TaskPage } from "./ChatPages/taskPage";
|
|
||||||
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
|
||||||
import { ViewController } from "./viewController";
|
import { ViewController } from "./viewController";
|
||||||
|
import "./homePage.css";
|
||||||
|
import { ChatViewToggleButton } from "./Components/chatViewToggleButton";
|
||||||
|
import { TaskPage } from "./ChatPages/taskPage";
|
||||||
|
import { SettingsPage } from "./ChatPages/settingsPage";
|
||||||
|
import { MessagePage } from "./ChatPages/messagePage";
|
||||||
|
import { CalendarPage } from "./ChatPages/calendarPage";
|
||||||
|
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
||||||
|
import ChatViewModel, { ChatPageTypes } from "../ViewModel/Chat/chatViewModel";
|
||||||
|
|
||||||
export function ChatPage(
|
export function ChatPage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import "./chatPage.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import "./chatPage.css";
|
||||||
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
|
||||||
import { ChatPage } from "./chatPage";
|
import { ChatPage } from "./chatPage";
|
||||||
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
||||||
|
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
||||||
|
|
||||||
export function ChatPageWrapper(
|
export function ChatPageWrapper(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
+9
-12
@@ -1,17 +1,14 @@
|
|||||||
import "./homePage.css";
|
|
||||||
|
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import "./homePage.css";
|
||||||
import { Option, StringToOption } from "./Components/option";
|
import { StringToOption } from "./Components/option";
|
||||||
|
|
||||||
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
|
||||||
import { ChatViewModelToChatEntry } from "./Components/chatEntry";
|
|
||||||
import ConnectionViewModel from "../ViewModel/Global/connectionViewModel";
|
|
||||||
import FileTransferViewModel from "../ViewModel/Global/fileTransferViewModel";
|
|
||||||
import SettingsViewModel from "../ViewModel/Global/settingsViewModel";
|
|
||||||
import StorageViewModel from "../ViewModel/Global/storageViewModel";
|
|
||||||
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
|
||||||
import { HomePageButton } from "./Components/homePageButton";
|
import { HomePageButton } from "./Components/homePageButton";
|
||||||
|
import { ChatViewModelToChatEntry } from "./Components/chatEntry";
|
||||||
|
import StorageViewModel from "../ViewModel/Global/storageViewModel";
|
||||||
|
import SettingsViewModel from "../ViewModel/Global/settingsViewModel";
|
||||||
|
import FileTransferViewModel from "../ViewModel/Global/fileTransferViewModel";
|
||||||
|
import CoreViewModel from "../ViewModel/Global/coreViewModel";
|
||||||
|
import ConnectionViewModel from "../ViewModel/Global/connectionViewModel";
|
||||||
|
import ChatListViewModel from "../ViewModel/Chat/chatListViewModel";
|
||||||
|
|
||||||
export function HomePage(
|
export function HomePage(
|
||||||
coreViewModel: CoreViewModel,
|
coreViewModel: CoreViewModel,
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ChatModel from "../../Model/Chat/chatModel";
|
|
||||||
import ChatViewModel from "./chatViewModel";
|
import ChatViewModel from "./chatViewModel";
|
||||||
import CoreViewModel from "../Global/coreViewModel";
|
|
||||||
import { IndexManager } from "../../Model/Utility/utility";
|
|
||||||
import SettingsViewModel from "../Global/settingsViewModel";
|
import SettingsViewModel from "../Global/settingsViewModel";
|
||||||
import ConnectionViewModel from "../Global/connectionViewModel";
|
|
||||||
import NotificationViewModel from "../Global/notificationViewModel";
|
import NotificationViewModel from "../Global/notificationViewModel";
|
||||||
|
import CoreViewModel from "../Global/coreViewModel";
|
||||||
|
import ConnectionViewModel from "../Global/connectionViewModel";
|
||||||
|
import { IndexManager } from "../../Model/Utility/utility";
|
||||||
|
import ChatModel from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export default class ChatListViewModel {
|
export default class ChatListViewModel {
|
||||||
notificationViewModel: NotificationViewModel;
|
notificationViewModel: NotificationViewModel;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import MessagePageViewModel from "../Pages/messagePageViewModel";
|
||||||
|
import CoreViewModel from "../Global/coreViewModel";
|
||||||
import {
|
import {
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
ChatMessageReaction,
|
ChatMessageReaction,
|
||||||
@@ -7,9 +8,6 @@ import {
|
|||||||
ReactionSymbols,
|
ReactionSymbols,
|
||||||
} from "../../Model/Chat/chatModel";
|
} from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
import CoreViewModel from "../Global/coreViewModel";
|
|
||||||
import MessagePageViewModel from "../Pages/messagePageViewModel";
|
|
||||||
|
|
||||||
export default class ChatMessageViewModel {
|
export default class ChatMessageViewModel {
|
||||||
// data
|
// data
|
||||||
chatMessage: ChatMessage;
|
chatMessage: ChatMessage;
|
||||||
|
|||||||
@@ -1,29 +1,26 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import ChatListViewModel from "./chatListViewModel";
|
||||||
|
import TaskPageViewModel from "../Pages/taskPageViewModel";
|
||||||
|
import SettingsPageViewModel from "../Pages/settingsPageViewModel";
|
||||||
|
import MessagePageViewModel from "../Pages/messagePageViewModel";
|
||||||
import CalendarPageViewModel, {
|
import CalendarPageViewModel, {
|
||||||
CALENDAR_EVENT_BOARD_ID,
|
CALENDAR_EVENT_BOARD_ID,
|
||||||
} from "../Pages/calendarPageViewModel";
|
} from "../Pages/calendarPageViewModel";
|
||||||
import ChatModel, {
|
import SettingsViewModel from "../Global/settingsViewModel";
|
||||||
ChatMessage,
|
import NotificationViewModel from "../Global/notificationViewModel";
|
||||||
ChatMessageReaction,
|
import CoreViewModel, { Context, ContextHost } from "../Global/coreViewModel";
|
||||||
} from "../../Model/Chat/chatModel";
|
import ConnectionViewModel from "../Global/connectionViewModel";
|
||||||
|
import { Colors } from "../../colors";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
|
import { Entry } from "../../View/Components/option";
|
||||||
import StorageModel, {
|
import StorageModel, {
|
||||||
StorageModelSubPaths,
|
StorageModelSubPaths,
|
||||||
filePaths,
|
filePaths,
|
||||||
} from "../../Model/Global/storageModel";
|
} from "../../Model/Global/storageModel";
|
||||||
|
import ChatModel, {
|
||||||
import ChatListViewModel from "./chatListViewModel";
|
ChatMessage,
|
||||||
import { Colors } from "../../colors";
|
ChatMessageReaction,
|
||||||
import CoreViewModel, { Context, ContextHost } from "../Global/coreViewModel";
|
} from "../../Model/Chat/chatModel";
|
||||||
import { Entry } from "../../View/Components/option";
|
|
||||||
import MessagePageViewModel from "../Pages/messagePageViewModel";
|
|
||||||
import SettingsPageViewModel from "../Pages/settingsPageViewModel";
|
|
||||||
import SettingsViewModel from "../Global/settingsViewModel";
|
|
||||||
import TaskPageViewModel from "../Pages/taskPageViewModel";
|
|
||||||
import ConnectionViewModel from "../Global/connectionViewModel";
|
|
||||||
import NotificationViewModel from "../Global/notificationViewModel";
|
|
||||||
import { v4 } from "uuid";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
|
|
||||||
export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
export default class ChatViewModel extends ContextHost<ChatPageTypes> {
|
||||||
calendarViewModel: CalendarPageViewModel;
|
calendarViewModel: CalendarPageViewModel;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import ConnectionModel from "../../Model/Global/connectionModel";
|
|
||||||
import CoreViewModel from "./coreViewModel";
|
import CoreViewModel from "./coreViewModel";
|
||||||
|
|
||||||
export default class ConnectionViewModel {
|
export default class ConnectionViewModel {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
import { v4 } from "uuid";
|
||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
import SettingsModel from "../../Model/Global/settingsModel";
|
|
||||||
import { allTranslations, Translations } from "../../View/translations";
|
import { allTranslations, Translations } from "../../View/translations";
|
||||||
|
import { HandlerManager } from "../../Model/Utility/utility";
|
||||||
import StorageModel from "../../Model/Global/storageModel";
|
import StorageModel from "../../Model/Global/storageModel";
|
||||||
|
import SettingsModel from "../../Model/Global/settingsModel";
|
||||||
|
import FileTransferModel from "../../Model/Global/fileTransferModel";
|
||||||
import ConnectionModel from "../../Model/Global/connectionModel";
|
import ConnectionModel from "../../Model/Global/connectionModel";
|
||||||
import ChatListModel from "../../Model/Chat/chatListModel";
|
import ChatListModel from "../../Model/Chat/chatListModel";
|
||||||
import FileTransferModel from "../../Model/Global/fileTransferModel";
|
|
||||||
import { v4 } from "uuid";
|
|
||||||
import { HandlerManager } from "../../Model/Utility/utility";
|
|
||||||
|
|
||||||
export default class CoreViewModel {
|
export default class CoreViewModel {
|
||||||
readonly BUILD = "Build 26.04.16.A";
|
readonly BUILD = "Build 26.04.16.A";
|
||||||
@@ -72,7 +72,8 @@ export default class CoreViewModel {
|
|||||||
|
|
||||||
handleChron = (): void => {
|
handleChron = (): void => {
|
||||||
const newDate = new Date();
|
const newDate = new Date();
|
||||||
if (this.unwrappedTodayDate.toDateString() == newDate.toDateString()) return;
|
if (this.unwrappedTodayDate.toDateString() == newDate.toDateString())
|
||||||
|
return;
|
||||||
this.todayDate.value = new Date();
|
this.todayDate.value = new Date();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import CoreViewModel, { Context } from "./coreViewModel";
|
||||||
import FileTransferModel, {
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
TransferData,
|
|
||||||
} from "../../Model/Global/fileTransferModel";
|
|
||||||
import StorageModel, {
|
import StorageModel, {
|
||||||
StorageModelSubPaths,
|
StorageModelSubPaths,
|
||||||
filePaths,
|
filePaths,
|
||||||
} from "../../Model/Global/storageModel";
|
} from "../../Model/Global/storageModel";
|
||||||
|
import { TransferData } from "../../Model/Global/fileTransferModel";
|
||||||
import ChatModel from "../../Model/Chat/chatModel";
|
import ChatModel from "../../Model/Chat/chatModel";
|
||||||
import CoreViewModel, { Context } from "./coreViewModel";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
|
|
||||||
export default class FileTransferViewModel extends Context {
|
export default class FileTransferViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
import ChatModel, { ChatMessage } from "../../Model/Chat/chatModel";
|
|
||||||
import ChatListViewModel from "../Chat/chatListViewModel";
|
|
||||||
import { ChatPageTypes } from "../Chat/chatViewModel";
|
import { ChatPageTypes } from "../Chat/chatViewModel";
|
||||||
|
import ChatListViewModel from "../Chat/chatListViewModel";
|
||||||
|
import ChatModel, { ChatMessage } from "../../Model/Chat/chatModel";
|
||||||
|
|
||||||
export default class NotificationViewModel {
|
export default class NotificationViewModel {
|
||||||
// data
|
// data
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import CoreViewModel, { Context } from "./coreViewModel";
|
import CoreViewModel, { Context } from "./coreViewModel";
|
||||||
import { Languages, ThemeSettings } from "../../Model/Global/settingsModel";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
|
import { Languages, ThemeSettings } from "../../Model/Global/settingsModel";
|
||||||
|
|
||||||
export default class SettingsViewModel extends Context {
|
export default class SettingsViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import CoreViewModel, { Context } from "./coreViewModel";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
import StorageModel, {
|
import StorageModel, {
|
||||||
PATH_COMPONENT_SEPARATOR,
|
PATH_COMPONENT_SEPARATOR,
|
||||||
} from "../../Model/Global/storageModel";
|
} from "../../Model/Global/storageModel";
|
||||||
|
|
||||||
import CoreViewModel, { Context } from "./coreViewModel";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
|
|
||||||
export default class StorageViewModel extends Context {
|
export default class StorageViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
isShowingStorageModal: React.State<boolean> = new React.State(false);
|
isShowingStorageModal: React.State<boolean> = new React.State(false);
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import TaskViewModel from "./taskViewModel";
|
||||||
|
import TaskPageViewModel from "./taskPageViewModel";
|
||||||
|
import TaskContainingPageViewModel from "./taskContainingPageViewModel";
|
||||||
|
import SearchViewModel from "../Utility/searchViewModel";
|
||||||
|
import CoreViewModel from "../Global/coreViewModel";
|
||||||
|
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||||
|
import { Colors } from "../../colors";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
import BoardsAndTasksModel, {
|
import BoardsAndTasksModel, {
|
||||||
BoardInfoFileContent,
|
BoardInfoFileContent,
|
||||||
TaskFileContent,
|
TaskFileContent,
|
||||||
} from "../../Model/Files/boardsAndTasksModel";
|
} from "../../Model/Files/boardsAndTasksModel";
|
||||||
|
|
||||||
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
|
||||||
import { Colors } from "../../colors";
|
|
||||||
import CoreViewModel from "../Global/coreViewModel";
|
|
||||||
import SearchViewModel from "../Utility/searchViewModel";
|
|
||||||
import TaskContainingPageViewModel from "./taskContainingPageViewModel";
|
|
||||||
import TaskPageViewModel from "./taskPageViewModel";
|
|
||||||
import TaskViewModel from "./taskViewModel";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
|
|
||||||
export default class BoardViewModel extends TaskContainingPageViewModel {
|
export default class BoardViewModel extends TaskContainingPageViewModel {
|
||||||
// state
|
// state
|
||||||
name: React.State<string> = new React.State("");
|
name: React.State<string> = new React.State("");
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import TaskViewModel from "./taskViewModel";
|
||||||
|
import TaskContainingPageViewModel from "./taskContainingPageViewModel";
|
||||||
|
import CoreViewModel from "../Global/coreViewModel";
|
||||||
|
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
|
import CalendarModel, { MonthGrid } from "../../Model/Files/calendarModel";
|
||||||
import BoardsAndTasksModel, {
|
import BoardsAndTasksModel, {
|
||||||
TaskFileContent,
|
TaskFileContent,
|
||||||
} from "../../Model/Files/boardsAndTasksModel";
|
} from "../../Model/Files/boardsAndTasksModel";
|
||||||
import CalendarModel, { MonthGrid } from "../../Model/Files/calendarModel";
|
|
||||||
|
|
||||||
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
|
||||||
import CoreViewModel from "../Global/coreViewModel";
|
|
||||||
import TaskContainingPageViewModel from "./taskContainingPageViewModel";
|
|
||||||
import TaskViewModel from "./taskViewModel";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
|
|
||||||
export const CALENDAR_EVENT_BOARD_ID = "events";
|
export const CALENDAR_EVENT_BOARD_ID = "events";
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
import ConnectionViewModel from "../Global/connectionViewModel";
|
|
||||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
|
||||||
import FileTransferViewModel from "../Global/fileTransferViewModel";
|
|
||||||
import SettingsViewModel from "../Global/settingsViewModel";
|
|
||||||
import StorageViewModel from "../Global/storageViewModel";
|
import StorageViewModel from "../Global/storageViewModel";
|
||||||
|
import SettingsViewModel from "../Global/settingsViewModel";
|
||||||
|
import FileTransferViewModel from "../Global/fileTransferViewModel";
|
||||||
|
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||||
|
import ConnectionViewModel from "../Global/connectionViewModel";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
|
|
||||||
export default class HomeViewModel extends Context {
|
export default class HomeViewModel extends Context {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import SearchViewModel from "../Utility/searchViewModel";
|
||||||
|
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||||
|
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||||
|
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
import {
|
import {
|
||||||
ChatMessage,
|
ChatMessage,
|
||||||
ChatMessageReaction,
|
ChatMessageReaction,
|
||||||
ReactionSymbols,
|
ReactionSymbols,
|
||||||
} from "../../Model/Chat/chatModel";
|
} from "../../Model/Chat/chatModel";
|
||||||
import ChatMessageViewModel from "../Chat/chatMessageViewModel";
|
|
||||||
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
|
||||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
|
||||||
import SearchViewModel from "../Utility/searchViewModel";
|
|
||||||
import { v4 } from "uuid";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
|
|
||||||
export default class MessagePageViewModel extends Context {
|
export default class MessagePageViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||||
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||||
import { Colors } from "../../colors";
|
import { Colors } from "../../colors";
|
||||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
|
||||||
|
|
||||||
export default class SettingsPageViewModel extends Context {
|
export default class SettingsPageViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import TaskViewModel from "./taskViewModel";
|
||||||
|
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||||
|
import ChatViewModel from "../Chat/chatViewModel";
|
||||||
|
import { IndexManager } from "../../Model/Utility/utility";
|
||||||
import BoardsAndTasksModel, {
|
import BoardsAndTasksModel, {
|
||||||
TaskFileContent,
|
TaskFileContent,
|
||||||
} from "../../Model/Files/boardsAndTasksModel";
|
} from "../../Model/Files/boardsAndTasksModel";
|
||||||
|
|
||||||
import ChatViewModel from "../Chat/chatViewModel";
|
|
||||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
|
||||||
import { IndexManager } from "../../Model/Utility/utility";
|
|
||||||
import TaskViewModel from "./taskViewModel";
|
|
||||||
|
|
||||||
export default class TaskContainingPageViewModel extends Context {
|
export default class TaskContainingPageViewModel extends Context {
|
||||||
// state
|
// state
|
||||||
readonly taskIndexManager = new IndexManager<TaskViewModel>(
|
readonly taskIndexManager = new IndexManager<TaskViewModel>(
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import BoardViewModel from "./boardViewModel";
|
||||||
|
import CoreViewModel, { ContextHost } from "../Global/coreViewModel";
|
||||||
|
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
|
import { IndexManager } from "../../Model/Utility/utility";
|
||||||
import BoardsAndTasksModel, {
|
import BoardsAndTasksModel, {
|
||||||
BoardInfoFileContent,
|
BoardInfoFileContent,
|
||||||
} from "../../Model/Files/boardsAndTasksModel";
|
} from "../../Model/Files/boardsAndTasksModel";
|
||||||
|
|
||||||
import BoardViewModel, { BoardPageTypes } from "./boardViewModel";
|
|
||||||
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
|
|
||||||
import CoreViewModel, { Context, ContextHost } from "../Global/coreViewModel";
|
|
||||||
import { IndexManager } from "../../Model/Utility/utility";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
|
|
||||||
export default class TaskPageViewModel extends ContextHost<string> {
|
export default class TaskPageViewModel extends ContextHost<string> {
|
||||||
// data
|
// data
|
||||||
readonly boardIndexManager = new IndexManager<BoardViewModel>(
|
readonly boardIndexManager = new IndexManager<BoardViewModel>(
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
import TaskContainingPageViewModel from "./taskContainingPageViewModel";
|
||||||
|
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
||||||
|
import ChatViewModel from "../Chat/chatViewModel";
|
||||||
|
import { ViewController } from "../../View/viewController";
|
||||||
|
import { CommonKeys } from "../../View/keystrokes";
|
||||||
|
import { localeCompare, padZero } from "../../Model/Utility/utility";
|
||||||
import BoardsAndTasksModel, {
|
import BoardsAndTasksModel, {
|
||||||
TaskFileContent,
|
TaskFileContent,
|
||||||
} from "../../Model/Files/boardsAndTasksModel";
|
} from "../../Model/Files/boardsAndTasksModel";
|
||||||
import { localeCompare, padZero } from "../../Model/Utility/utility";
|
|
||||||
|
|
||||||
import ChatViewModel from "../Chat/chatViewModel";
|
|
||||||
import CoreViewModel, { Context } from "../Global/coreViewModel";
|
|
||||||
import TaskContainingPageViewModel from "./taskContainingPageViewModel";
|
|
||||||
import { CommonKeys } from "../../View/keystrokes";
|
|
||||||
import { ViewController } from "../../View/viewController";
|
|
||||||
|
|
||||||
export default class TaskViewModel extends Context {
|
export default class TaskViewModel extends Context {
|
||||||
// util
|
// util
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { checkDoesObjectMatchSearch } from "../../Model/Utility/utility";
|
import { checkDoesObjectMatchSearch } from "../../Model/Utility/utility";
|
||||||
|
|
||||||
export default class SearchViewModel<T> {
|
export default class SearchViewModel<T> {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import TaskViewModel from "../Pages/taskViewModel";
|
import TaskViewModel from "../Pages/taskViewModel";
|
||||||
|
|
||||||
export default class TaskPropertyBulkChangeViewModel {
|
export default class TaskPropertyBulkChangeViewModel {
|
||||||
|
|||||||
+20
-22
@@ -1,28 +1,26 @@
|
|||||||
import "./base.css";
|
import * as React from "bloatless-react";
|
||||||
import "./colors.css";
|
import "./colors.css";
|
||||||
import "./coloredTile.css";
|
import "./coloredTile.css";
|
||||||
|
import "./base.css";
|
||||||
import * as React from "bloatless-react";
|
|
||||||
|
|
||||||
import ChatListModel from "./Model/Chat/chatListModel";
|
|
||||||
import ChatListViewModel from "./ViewModel/Chat/chatListViewModel";
|
|
||||||
import { ChatPageWrapper } from "./View/chatPageWrapper";
|
|
||||||
import { ConnectionModal } from "./View/Modals/connectionModal";
|
|
||||||
import ConnectionModel from "./Model/Global/connectionModel";
|
|
||||||
import ConnectionViewModel from "./ViewModel/Global/connectionViewModel";
|
|
||||||
import CoreViewModel from "./ViewModel/Global/coreViewModel";
|
|
||||||
import { DataTransferModalWrapper } from "./View/Modals/dataTransferModal";
|
|
||||||
import FileTransferModel from "./Model/Global/fileTransferModel";
|
|
||||||
import FileTransferViewModel from "./ViewModel/Global/fileTransferViewModel";
|
|
||||||
import { HomePage } from "./View/homePage";
|
|
||||||
import SettingsModel from "./Model/Global/settingsModel";
|
|
||||||
import SettingsViewModel from "./ViewModel/Global/settingsViewModel";
|
|
||||||
import { StorageModal } from "./View/Modals/storageModal";
|
|
||||||
import StorageModel from "./Model/Global/storageModel";
|
|
||||||
import StorageViewModel from "./ViewModel/Global/storageViewModel";
|
|
||||||
import v1Upgrader from "./Upgrader/v1";
|
|
||||||
import { SettingsModal } from "./View/Modals/settingsModal";
|
|
||||||
import HomeViewModel from "./ViewModel/Pages/homeViewModel";
|
import HomeViewModel from "./ViewModel/Pages/homeViewModel";
|
||||||
|
import StorageViewModel from "./ViewModel/Global/storageViewModel";
|
||||||
|
import SettingsViewModel from "./ViewModel/Global/settingsViewModel";
|
||||||
|
import FileTransferViewModel from "./ViewModel/Global/fileTransferViewModel";
|
||||||
|
import CoreViewModel from "./ViewModel/Global/coreViewModel";
|
||||||
|
import ConnectionViewModel from "./ViewModel/Global/connectionViewModel";
|
||||||
|
import ChatListViewModel from "./ViewModel/Chat/chatListViewModel";
|
||||||
|
import { HomePage } from "./View/homePage";
|
||||||
|
import { ChatPageWrapper } from "./View/chatPageWrapper";
|
||||||
|
import { StorageModal } from "./View/Modals/storageModal";
|
||||||
|
import { SettingsModal } from "./View/Modals/settingsModal";
|
||||||
|
import { DataTransferModalWrapper } from "./View/Modals/dataTransferModal";
|
||||||
|
import { ConnectionModal } from "./View/Modals/connectionModal";
|
||||||
|
import v1Upgrader from "./Upgrader/v1";
|
||||||
|
import StorageModel from "./Model/Global/storageModel";
|
||||||
|
import SettingsModel from "./Model/Global/settingsModel";
|
||||||
|
import FileTransferModel from "./Model/Global/fileTransferModel";
|
||||||
|
import ConnectionModel from "./Model/Global/connectionModel";
|
||||||
|
import ChatListModel from "./Model/Chat/chatListModel";
|
||||||
|
|
||||||
// models
|
// models
|
||||||
const storageModel = new StorageModel();
|
const storageModel = new StorageModel();
|
||||||
|
|||||||
Reference in New Issue
Block a user