implement uniform sorting on all views
This commit is contained in:
Vendored
+51
-35
@@ -427,6 +427,19 @@
|
|||||||
var stringToOptionTag = (value) => {
|
var stringToOptionTag = (value) => {
|
||||||
return /* @__PURE__ */ createElement("option", null, value);
|
return /* @__PURE__ */ createElement("option", null, value);
|
||||||
};
|
};
|
||||||
|
function getRawObjectIndex(latest) {
|
||||||
|
const dateString = latest.date || "0000-00-00";
|
||||||
|
const [year, month, date] = dateString.split("-");
|
||||||
|
const timeString = latest.time || "00:00";
|
||||||
|
const [hour, minute] = timeString.split(":");
|
||||||
|
const hourInMinutes = parseInt(hour) * 60;
|
||||||
|
const minutesTotal = parseInt(minute) + hourInMinutes;
|
||||||
|
const paddedMinutes = minutesTotal.toString().padStart(4, "0");
|
||||||
|
const priority = latest.priority ?? 0;
|
||||||
|
const priorityInverse = 100 - priority;
|
||||||
|
const paddedPriority = priorityInverse.toString().padStart(3, "0");
|
||||||
|
return `${year}${month}${date}${paddedMinutes}${paddedPriority}`;
|
||||||
|
}
|
||||||
|
|
||||||
// src/translations.ts
|
// src/translations.ts
|
||||||
var englishTranslations = {
|
var englishTranslations = {
|
||||||
@@ -760,6 +773,14 @@
|
|||||||
var translation = allTranslations[language] ?? allTranslations.en;
|
var translation = allTranslations[language] ?? allTranslations.en;
|
||||||
|
|
||||||
// src/Model/chatModel.ts
|
// src/Model/chatModel.ts
|
||||||
|
var MessageObjectWithIndex = class {
|
||||||
|
constructor(messageObject, index = 0) {
|
||||||
|
this.id = messageObject.id;
|
||||||
|
this.title = messageObject.title;
|
||||||
|
this.contentVersions = messageObject.contentVersions;
|
||||||
|
this.index = new State(index);
|
||||||
|
}
|
||||||
|
};
|
||||||
var Chat = class {
|
var Chat = class {
|
||||||
id;
|
id;
|
||||||
viewType;
|
viewType;
|
||||||
@@ -1582,7 +1603,7 @@
|
|||||||
const [icon, value] = field;
|
const [icon, value] = field;
|
||||||
return /* @__PURE__ */ createElement("span", { class: "flex-row control-gap flex align-center padding-right ellipsis" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icon), /* @__PURE__ */ createElement("span", { class: "ellipsis" }, value));
|
return /* @__PURE__ */ createElement("span", { class: "flex-row control-gap flex align-center padding-right ellipsis" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icon), /* @__PURE__ */ createElement("span", { class: "ellipsis" }, value));
|
||||||
});
|
});
|
||||||
return /* @__PURE__ */ createElement(
|
const view = /* @__PURE__ */ createElement(
|
||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
class: "tile flex-no",
|
class: "tile flex-no",
|
||||||
@@ -1599,6 +1620,10 @@
|
|||||||
...fieldElements
|
...fieldElements
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
messageObject.index.subscribe((newIndex) => {
|
||||||
|
view.style.order = newIndex;
|
||||||
|
});
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/Objects/objectGridView.tsx
|
// src/Views/Objects/objectGridView.tsx
|
||||||
@@ -1652,22 +1677,12 @@
|
|||||||
messageObjects.value.forEach(processObject);
|
messageObjects.value.forEach(processObject);
|
||||||
});
|
});
|
||||||
const objectConverter = (messageObject) => {
|
const objectConverter = (messageObject) => {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
return ObjectEntryView(
|
||||||
const timeString = latest.time || "00:00";
|
|
||||||
const [hour, minute] = timeString.split(":");
|
|
||||||
const hourInMinutes = parseInt(hour) * 60;
|
|
||||||
const minutesTotal = parseInt(minute) + hourInMinutes;
|
|
||||||
const priority = latest.priority ?? 0;
|
|
||||||
const priorityInverse = 100 - priority;
|
|
||||||
const order = `${minutesTotal}${priorityInverse}`;
|
|
||||||
const view = ObjectEntryView(
|
|
||||||
chat,
|
chat,
|
||||||
messageObject,
|
messageObject,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
);
|
);
|
||||||
view.style.order = order;
|
|
||||||
return view;
|
|
||||||
};
|
};
|
||||||
return /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement(
|
||||||
"div",
|
"div",
|
||||||
@@ -1701,16 +1716,10 @@
|
|||||||
const isToday = today.getDate() == dateObject.getUTCDate() && today.getMonth() == dateObject.getUTCMonth() && today.getFullYear() == dateObject.getUTCFullYear();
|
const isToday = today.getDate() == dateObject.getUTCDate() && today.getMonth() == dateObject.getUTCMonth() && today.getFullYear() == dateObject.getUTCFullYear();
|
||||||
messageObjects.handleAddition(processObject);
|
messageObjects.handleAddition(processObject);
|
||||||
const objectConverter = (messageObject) => {
|
const objectConverter = (messageObject) => {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
|
||||||
const timeString = latest.time || "00:00";
|
|
||||||
const [hour, minute] = timeString.split(":");
|
|
||||||
const hourInMinutes = parseInt(hour) * 60;
|
|
||||||
const minutesTotal = parseInt(minute) + hourInMinutes;
|
|
||||||
const priority = latest.priority ?? 0;
|
|
||||||
const priorityInverse = 100 - priority;
|
|
||||||
const order = `${minutesTotal}${priorityInverse}`;
|
|
||||||
const view = /* @__PURE__ */ createElement("span", { class: "secondary ellipsis" }, chat.getObjectTitle(messageObject));
|
const view = /* @__PURE__ */ createElement("span", { class: "secondary ellipsis" }, chat.getObjectTitle(messageObject));
|
||||||
view.style.order = order;
|
messageObject.index.subscribe((newIndex) => {
|
||||||
|
view.style.order = newIndex;
|
||||||
|
});
|
||||||
return view;
|
return view;
|
||||||
};
|
};
|
||||||
return /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement(
|
||||||
@@ -1774,7 +1783,6 @@
|
|||||||
monthGridCells.value = [];
|
monthGridCells.value = [];
|
||||||
currentDate.setUTCDate(1);
|
currentDate.setUTCDate(1);
|
||||||
currentDate.setUTCMonth(newSelectedDate.getMonth());
|
currentDate.setUTCMonth(newSelectedDate.getMonth());
|
||||||
console.log(currentDate);
|
|
||||||
for (let i = 0; i < 7; i++) {
|
for (let i = 0; i < 7; i++) {
|
||||||
monthGridCells.value.push(
|
monthGridCells.value.push(
|
||||||
/* @__PURE__ */ createElement("b", { class: "secondary ellipsis width-100" }, translation.weekdays[i])
|
/* @__PURE__ */ createElement("b", { class: "secondary ellipsis width-100" }, translation.weekdays[i])
|
||||||
@@ -1917,14 +1925,12 @@
|
|||||||
chat.addObjectAndSend(messageObject);
|
chat.addObjectAndSend(messageObject);
|
||||||
}
|
}
|
||||||
const itemToViewEntry = (kanbanBoardItem) => {
|
const itemToViewEntry = (kanbanBoardItem) => {
|
||||||
const view = ObjectEntryView(
|
return ObjectEntryView(
|
||||||
chat,
|
chat,
|
||||||
kanbanBoardItem.messageObject,
|
kanbanBoardItem.messageObject,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
);
|
);
|
||||||
view.style.order = kanbanBoardItem.priority * -1;
|
|
||||||
return view;
|
|
||||||
};
|
};
|
||||||
return /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement(
|
||||||
"div",
|
"div",
|
||||||
@@ -2291,7 +2297,7 @@
|
|||||||
[appliedFilter, resultCount],
|
[appliedFilter, resultCount],
|
||||||
() => translation.searchTitleText(appliedFilter.value, resultCount.value)
|
() => translation.searchTitleText(appliedFilter.value, resultCount.value)
|
||||||
);
|
);
|
||||||
const showingMessageObjects = new MapState();
|
const visibleMessageObjects = new MapState();
|
||||||
const isFilterEmpty = createProxyState(
|
const isFilterEmpty = createProxyState(
|
||||||
[appliedFilter],
|
[appliedFilter],
|
||||||
() => appliedFilter.value == ""
|
() => appliedFilter.value == ""
|
||||||
@@ -2305,21 +2311,21 @@
|
|||||||
if (!previousObjectSearches.value.has(appliedFilter.value))
|
if (!previousObjectSearches.value.has(appliedFilter.value))
|
||||||
previousObjectSearches.add(appliedFilter.value);
|
previousObjectSearches.add(appliedFilter.value);
|
||||||
const allObjects = [...chat.objects.value.values()];
|
const allObjects = [...chat.objects.value.values()];
|
||||||
allObjects.forEach((object, i) => {
|
allObjects.forEach((messageObject, i) => {
|
||||||
const doesMatch = checkIfMatchesFilter(object);
|
const doesMatch = checkIfMatchesFilter(messageObject);
|
||||||
if (doesMatch) {
|
if (doesMatch) {
|
||||||
showingMessageObjects.set(object.id, object);
|
visibleMessageObjects.set(messageObject.id, new MessageObjectWithIndex(messageObject));
|
||||||
} else {
|
} else {
|
||||||
showingMessageObjects.remove(object.id);
|
visibleMessageObjects.remove(messageObject.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
resultCount.value = showingMessageObjects.value.size;
|
resultCount.value = visibleMessageObjects.value.size;
|
||||||
}
|
}
|
||||||
chat.objects.handleAddition((messageObject) => {
|
chat.objects.handleAddition((messageObject) => {
|
||||||
if (checkIfMatchesFilter(messageObject) == false) return;
|
if (checkIfMatchesFilter(messageObject) == false) return;
|
||||||
showingMessageObjects.set(messageObject.id, messageObject);
|
visibleMessageObjects.set(messageObject.id, new MessageObjectWithIndex(messageObject));
|
||||||
chat.objects.handleRemoval(messageObject, () => {
|
chat.objects.handleRemoval(messageObject, () => {
|
||||||
showingMessageObjects.remove(messageObject.id);
|
visibleMessageObjects.remove(messageObject.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
function checkIfMatchesFilter(messageObject) {
|
function checkIfMatchesFilter(messageObject) {
|
||||||
@@ -2347,6 +2353,16 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
applyFilter();
|
applyFilter();
|
||||||
|
visibleMessageObjects.subscribe((visibleMessageObjects2) => {
|
||||||
|
let indices = [...visibleMessageObjects2.values()].map((messageObject) => {
|
||||||
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
|
return getRawObjectIndex(latest);
|
||||||
|
}).sort();
|
||||||
|
visibleMessageObjects2.forEach((messageObject) => {
|
||||||
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
|
messageObject.index.value = indices.indexOf(getRawObjectIndex(latest));
|
||||||
|
});
|
||||||
|
});
|
||||||
const objectModal = createProxyState(
|
const objectModal = createProxyState(
|
||||||
[chat.objects, selectedObject],
|
[chat.objects, selectedObject],
|
||||||
() => {
|
() => {
|
||||||
@@ -2375,7 +2391,7 @@
|
|||||||
}
|
}
|
||||||
return getViewFunction()(
|
return getViewFunction()(
|
||||||
chat,
|
chat,
|
||||||
showingMessageObjects,
|
visibleMessageObjects,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
);
|
);
|
||||||
@@ -2432,7 +2448,7 @@
|
|||||||
translation.reset
|
translation.reset
|
||||||
), /* @__PURE__ */ createElement("button", { class: "width-50 flex primary", "on:click": applyFilter }, translation.search, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("b", { class: "secondary", "subscribe:innerText": resultText }), ObjectGridView(
|
), /* @__PURE__ */ createElement("button", { class: "width-50 flex primary", "on:click": applyFilter }, translation.search, /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_forward"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("b", { class: "secondary", "subscribe:innerText": resultText }), ObjectGridView(
|
||||||
chat,
|
chat,
|
||||||
showingMessageObjects,
|
visibleMessageObjects,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
)), /* @__PURE__ */ createElement("button", { "on:click": closeFilters }, translation.close, /* @__PURE__ */ createElement("span", { class: "icon" }, "close")))), /* @__PURE__ */ createElement("div", { "children:set": objectModal }));
|
)), /* @__PURE__ */ createElement("button", { "on:click": closeFilters }, translation.close, /* @__PURE__ */ createElement("span", { class: "icon" }, "close")))), /* @__PURE__ */ createElement("div", { "children:set": objectModal }));
|
||||||
|
|||||||
@@ -49,6 +49,19 @@ export interface MessageObjectContent {
|
|||||||
time?: string;
|
time?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MessageObjectWithIndex extends MessageObject {
|
||||||
|
index: React.State<number>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MessageObjectWithIndex implements MessageObjectWithIndex {
|
||||||
|
constructor(messageObject: MessageObject, index: number = 0) {
|
||||||
|
this.id = messageObject.id;
|
||||||
|
this.title = messageObject.title;
|
||||||
|
this.contentVersions = messageObject.contentVersions;
|
||||||
|
this.index = new React.State(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// chat
|
// chat
|
||||||
export class Chat {
|
export class Chat {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { ObjectGridView } from "./objectGridView";
|
import { ObjectGridView } from "./objectGridView";
|
||||||
import { translation } from "../../translations";
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
export function AllObjectsView(
|
export function AllObjectsView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects: React.MapState<MessageObject>,
|
messageObjects: React.MapState<MessageObjectWithIndex>,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { DayView } from "./dayView";
|
import { DayView } from "./dayView";
|
||||||
import { MiniatureDayView } from "./miniatureDayView";
|
import { MiniatureDayView } from "./miniatureDayView";
|
||||||
@@ -9,7 +9,7 @@ import { translation } from "../../translations";
|
|||||||
|
|
||||||
export function CalendarView(
|
export function CalendarView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects: React.MapState<MessageObject>,
|
messageObjects: React.MapState<MessageObjectWithIndex>,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { ObjectEntryView } from "./objectEntryView";
|
import { ObjectEntryView } from "./objectEntryView";
|
||||||
import { dayInCalendar } from "../../Model/model";
|
import { dayInCalendar } from "../../Model/model";
|
||||||
@@ -8,14 +8,14 @@ import { dayInCalendar } from "../../Model/model";
|
|||||||
export function DayView(
|
export function DayView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects:
|
messageObjects:
|
||||||
| React.ListState<MessageObject>
|
| React.ListState<MessageObjectWithIndex>
|
||||||
| React.MapState<MessageObject>,
|
| React.MapState<MessageObjectWithIndex>,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
const objectsForDayView = new React.ListState<MessageObject>();
|
const objectsForDayView = new React.ListState<MessageObjectWithIndex>();
|
||||||
|
|
||||||
function processObject(messageObject: MessageObject) {
|
function processObject(messageObject: MessageObjectWithIndex) {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
if (!latest.date || latest.date != dayInCalendar.value) return;
|
if (!latest.date || latest.date != dayInCalendar.value) return;
|
||||||
|
|
||||||
@@ -31,26 +31,15 @@ export function DayView(
|
|||||||
messageObjects.value.forEach(processObject);
|
messageObjects.value.forEach(processObject);
|
||||||
})
|
})
|
||||||
|
|
||||||
const objectConverter: React.StateItemConverter<MessageObject> = (
|
const objectConverter: React.StateItemConverter<MessageObjectWithIndex> = (
|
||||||
messageObject
|
messageObject
|
||||||
) => {
|
) => {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
return ObjectEntryView(
|
||||||
const timeString = latest.time || "00:00";
|
|
||||||
const [hour, minute] = timeString.split(":");
|
|
||||||
const hourInMinutes = parseInt(hour) * 60;
|
|
||||||
const minutesTotal = parseInt(minute) + hourInMinutes;
|
|
||||||
const priority = latest.priority ?? 0;
|
|
||||||
const priorityInverse = 100 - priority;
|
|
||||||
const order = `${minutesTotal}${priorityInverse}`;
|
|
||||||
|
|
||||||
const view = ObjectEntryView(
|
|
||||||
chat,
|
chat,
|
||||||
messageObject,
|
messageObject,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
);
|
);
|
||||||
view.style.order = order;
|
|
||||||
return view;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { ObjectEntryView } from "./objectEntryView";
|
import { ObjectEntryView } from "./objectEntryView";
|
||||||
import { RenameView } from "../renameView";
|
import { RenameView } from "../renameView";
|
||||||
@@ -17,7 +17,7 @@ interface KanbanBoardItem {
|
|||||||
|
|
||||||
export function KanbanView(
|
export function KanbanView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects: React.MapState<MessageObject>,
|
messageObjects: React.MapState<MessageObjectWithIndex>,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
@@ -116,14 +116,12 @@ function KanbanBoardView(
|
|||||||
const itemToViewEntry: React.StateItemConverter<KanbanBoardItem> = (
|
const itemToViewEntry: React.StateItemConverter<KanbanBoardItem> = (
|
||||||
kanbanBoardItem
|
kanbanBoardItem
|
||||||
) => {
|
) => {
|
||||||
const view = ObjectEntryView(
|
return ObjectEntryView(
|
||||||
chat,
|
chat,
|
||||||
kanbanBoardItem.messageObject,
|
kanbanBoardItem.messageObject,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
);
|
);
|
||||||
view.style.order = kanbanBoardItem.priority * -1;
|
|
||||||
return view;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { dayInCalendar } from "../../Model/model";
|
import { dayInCalendar } from "../../Model/model";
|
||||||
|
import { getRawObjectIndex } from "../../utility";
|
||||||
|
|
||||||
export function MiniatureDayView(
|
export function MiniatureDayView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects:
|
messageObjects:
|
||||||
| React.ListState<MessageObject>
|
| React.ListState<MessageObjectWithIndex>
|
||||||
| React.MapState<MessageObject>,
|
| React.MapState<MessageObjectWithIndex>,
|
||||||
dateObject: Date
|
dateObject: Date
|
||||||
) {
|
) {
|
||||||
const objectsForDayView = new React.ListState<MessageObject>();
|
const objectsForDayView = new React.ListState<MessageObject>();
|
||||||
|
|
||||||
const dateString = dateObject.toISOString().split("T")[0];
|
const dateString = dateObject.toISOString().split("T")[0];
|
||||||
|
|
||||||
function processObject(messageObject: MessageObject) {
|
function processObject(messageObject: MessageObjectWithIndex) {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
if (!latest.date || latest.date != dateString) return;
|
if (!latest.date || latest.date != dateString) return;
|
||||||
|
|
||||||
@@ -41,24 +42,17 @@ export function MiniatureDayView(
|
|||||||
|
|
||||||
messageObjects.handleAddition(processObject);
|
messageObjects.handleAddition(processObject);
|
||||||
|
|
||||||
const objectConverter: React.StateItemConverter<MessageObject> = (
|
const objectConverter: React.StateItemConverter<MessageObjectWithIndex> = (
|
||||||
messageObject
|
messageObject
|
||||||
) => {
|
) => {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
|
||||||
const timeString = latest.time || "00:00";
|
|
||||||
const [hour, minute] = timeString.split(":");
|
|
||||||
const hourInMinutes = parseInt(hour) * 60;
|
|
||||||
const minutesTotal = parseInt(minute) + hourInMinutes;
|
|
||||||
const priority = latest.priority ?? 0;
|
|
||||||
const priorityInverse = 100 - priority;
|
|
||||||
const order = `${minutesTotal}${priorityInverse}`;
|
|
||||||
|
|
||||||
const view = (
|
const view = (
|
||||||
<span class="secondary ellipsis">
|
<span class="secondary ellipsis">
|
||||||
{chat.getObjectTitle(messageObject)}
|
{chat.getObjectTitle(messageObject)}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
view.style.order = order;
|
messageObject.index.subscribe(newIndex => {
|
||||||
|
view.style.order = newIndex;
|
||||||
|
})
|
||||||
return view;
|
return view;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { ObjectGridView } from "./objectGridView";
|
import { ObjectGridView } from "./objectGridView";
|
||||||
|
|
||||||
export function NoteObjectsView(
|
export function NoteObjectsView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects: React.MapState<MessageObject>,
|
messageObjects: React.MapState<MessageObjectWithIndex>,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ import {
|
|||||||
Chat,
|
Chat,
|
||||||
MessageObject,
|
MessageObject,
|
||||||
MessageObjectContent,
|
MessageObjectContent,
|
||||||
|
MessageObjectWithIndex,
|
||||||
} from "../../Model/chatModel";
|
} from "../../Model/chatModel";
|
||||||
|
|
||||||
import { icons } from "../../icons";
|
import { icons } from "../../icons";
|
||||||
|
|
||||||
export function ObjectEntryView(
|
export function ObjectEntryView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObject: MessageObject,
|
messageObject: MessageObjectWithIndex,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
@@ -54,7 +55,7 @@ export function ObjectEntryView(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
const view = (
|
||||||
<button
|
<button
|
||||||
class="tile flex-no"
|
class="tile flex-no"
|
||||||
on:click={select}
|
on:click={select}
|
||||||
@@ -73,4 +74,8 @@ export function ObjectEntryView(
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
messageObject.index.subscribe(newIndex => {
|
||||||
|
view.style.order = newIndex;
|
||||||
|
})
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { ObjectEntryView } from "./objectEntryView";
|
import { ObjectEntryView } from "./objectEntryView";
|
||||||
|
|
||||||
export function ObjectGridView(
|
export function ObjectGridView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects:
|
messageObjects:
|
||||||
| React.ListState<MessageObject>
|
| React.ListState<MessageObjectWithIndex>
|
||||||
| React.MapState<MessageObject>,
|
| React.MapState<MessageObjectWithIndex>,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
const objectConverter: React.StateItemConverter<MessageObject> = (
|
const objectConverter: React.StateItemConverter<MessageObjectWithIndex> = (
|
||||||
messageObject
|
messageObject
|
||||||
) => {
|
) => {
|
||||||
return ObjectEntryView(
|
return ObjectEntryView(
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import {
|
||||||
|
Chat,
|
||||||
|
MessageObject,
|
||||||
|
MessageObjectWithIndex,
|
||||||
|
} from "../../Model/chatModel";
|
||||||
|
import { getRawObjectIndex, stringToOptionTag } from "../../utility";
|
||||||
import { objectFilterInput, previousObjectSearches } from "../../Model/model";
|
import { objectFilterInput, previousObjectSearches } from "../../Model/model";
|
||||||
|
|
||||||
import { AllObjectsView } from "./allObjectsView";
|
import { AllObjectsView } from "./allObjectsView";
|
||||||
@@ -11,7 +16,6 @@ import { ObjectDetailModal } from "./objectDetailModal";
|
|||||||
import { ObjectGridView } from "./objectGridView";
|
import { ObjectGridView } from "./objectGridView";
|
||||||
import { StatusView } from "./statusView";
|
import { StatusView } from "./statusView";
|
||||||
import { icons } from "../../icons";
|
import { icons } from "../../icons";
|
||||||
import { stringToOptionTag } from "../../utility";
|
|
||||||
import { translation } from "../../translations";
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
export const viewTypes = {
|
export const viewTypes = {
|
||||||
@@ -51,7 +55,7 @@ export function ObjectPane(chat: Chat) {
|
|||||||
const resultText = React.createProxyState([appliedFilter, resultCount], () =>
|
const resultText = React.createProxyState([appliedFilter, resultCount], () =>
|
||||||
translation.searchTitleText(appliedFilter.value, resultCount.value)
|
translation.searchTitleText(appliedFilter.value, resultCount.value)
|
||||||
);
|
);
|
||||||
const showingMessageObjects = new React.MapState<MessageObject>();
|
const visibleMessageObjects = new React.MapState<MessageObjectWithIndex>();
|
||||||
const isFilterEmpty = React.createProxyState(
|
const isFilterEmpty = React.createProxyState(
|
||||||
[appliedFilter],
|
[appliedFilter],
|
||||||
() => appliedFilter.value == ""
|
() => appliedFilter.value == ""
|
||||||
@@ -68,22 +72,22 @@ export function ObjectPane(chat: Chat) {
|
|||||||
previousObjectSearches.add(appliedFilter.value);
|
previousObjectSearches.add(appliedFilter.value);
|
||||||
|
|
||||||
const allObjects = [...chat.objects.value.values()];
|
const allObjects = [...chat.objects.value.values()];
|
||||||
allObjects.forEach((object, i) => {
|
allObjects.forEach((messageObject, i) => {
|
||||||
const doesMatch = checkIfMatchesFilter(object);
|
const doesMatch = checkIfMatchesFilter(messageObject);
|
||||||
if (doesMatch) {
|
if (doesMatch) {
|
||||||
showingMessageObjects.set(object.id, object);
|
visibleMessageObjects.set(messageObject.id, new MessageObjectWithIndex(messageObject));
|
||||||
} else {
|
} else {
|
||||||
showingMessageObjects.remove(object.id);
|
visibleMessageObjects.remove(messageObject.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
resultCount.value = showingMessageObjects.value.size;
|
resultCount.value = visibleMessageObjects.value.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
chat.objects.handleAddition((messageObject) => {
|
chat.objects.handleAddition((messageObject) => {
|
||||||
if (checkIfMatchesFilter(messageObject) == false) return;
|
if (checkIfMatchesFilter(messageObject) == false) return;
|
||||||
showingMessageObjects.set(messageObject.id, messageObject);
|
visibleMessageObjects.set(messageObject.id, new MessageObjectWithIndex(messageObject));
|
||||||
chat.objects.handleRemoval(messageObject, () => {
|
chat.objects.handleRemoval(messageObject, () => {
|
||||||
showingMessageObjects.remove(messageObject.id);
|
visibleMessageObjects.remove(messageObject.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -122,6 +126,21 @@ export function ObjectPane(chat: Chat) {
|
|||||||
|
|
||||||
applyFilter();
|
applyFilter();
|
||||||
|
|
||||||
|
// sorting
|
||||||
|
visibleMessageObjects.subscribe((visibleMessageObjects) => {
|
||||||
|
let indices = [...visibleMessageObjects.values()]
|
||||||
|
.map((messageObject) => {
|
||||||
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
|
return getRawObjectIndex(latest);
|
||||||
|
})
|
||||||
|
.sort();
|
||||||
|
|
||||||
|
visibleMessageObjects.forEach((messageObject) => {
|
||||||
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
|
messageObject.index.value = indices.indexOf(getRawObjectIndex(latest));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// view
|
// view
|
||||||
const objectModal = React.createProxyState(
|
const objectModal = React.createProxyState(
|
||||||
[chat.objects, selectedObject],
|
[chat.objects, selectedObject],
|
||||||
@@ -154,7 +173,7 @@ export function ObjectPane(chat: Chat) {
|
|||||||
|
|
||||||
return getViewFunction()(
|
return getViewFunction()(
|
||||||
chat,
|
chat,
|
||||||
showingMessageObjects,
|
visibleMessageObjects,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
);
|
);
|
||||||
@@ -238,7 +257,7 @@ export function ObjectPane(chat: Chat) {
|
|||||||
|
|
||||||
{ObjectGridView(
|
{ObjectGridView(
|
||||||
chat,
|
chat,
|
||||||
showingMessageObjects,
|
visibleMessageObjects,
|
||||||
selectedObject,
|
selectedObject,
|
||||||
isShowingObjectModal
|
isShowingObjectModal
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject, MessageObjectWithIndex } from "../../Model/chatModel";
|
||||||
|
|
||||||
import { ObjectEntryView } from "./objectEntryView";
|
import { ObjectEntryView } from "./objectEntryView";
|
||||||
import { RenameView } from "../renameView";
|
import { RenameView } from "../renameView";
|
||||||
@@ -29,7 +29,7 @@ interface StatusData {
|
|||||||
|
|
||||||
export function StatusView(
|
export function StatusView(
|
||||||
chat: Chat,
|
chat: Chat,
|
||||||
messageObjects: React.MapState<MessageObject>,
|
messageObjects: React.MapState<MessageObjectWithIndex>,
|
||||||
selectedObject: React.State<MessageObject | undefined>,
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
isShowingObjectModal: React.State<boolean>
|
isShowingObjectModal: React.State<boolean>
|
||||||
) {
|
) {
|
||||||
|
|||||||
+23
-2
@@ -1,7 +1,6 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import { MessageObject } from "./Model/chatModel";
|
import { MessageObjectContent } from "./Model/chatModel";
|
||||||
import { ObjectEntryView } from "./Views/Objects/objectEntryView";
|
|
||||||
|
|
||||||
export const storageKeys = {
|
export const storageKeys = {
|
||||||
viewType(id: string): string {
|
viewType(id: string): string {
|
||||||
@@ -48,3 +47,25 @@ export const storageKeys = {
|
|||||||
export const stringToOptionTag: React.StateItemConverter<string> = (value) => {
|
export const stringToOptionTag: React.StateItemConverter<string> = (value) => {
|
||||||
return <option>{value}</option>;
|
return <option>{value}</option>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getRawObjectIndex(latest: MessageObjectContent): string {
|
||||||
|
// date
|
||||||
|
const dateString = latest.date || "0000-00-00";
|
||||||
|
const [year, month, date] = dateString.split("-")
|
||||||
|
|
||||||
|
// time
|
||||||
|
const timeString = latest.time || "00:00";
|
||||||
|
const [hour, minute] = timeString.split(":");
|
||||||
|
|
||||||
|
const hourInMinutes = parseInt(hour) * 60;
|
||||||
|
const minutesTotal = parseInt(minute) + hourInMinutes;
|
||||||
|
const paddedMinutes = minutesTotal.toString().padStart(4, "0")
|
||||||
|
|
||||||
|
// priority
|
||||||
|
const priority = latest.priority ?? 0;
|
||||||
|
const priorityInverse = 100 - priority;
|
||||||
|
const paddedPriority = priorityInverse.toString().padStart(3, "0");
|
||||||
|
|
||||||
|
// final
|
||||||
|
return `${year}${month}${date}${paddedMinutes}${paddedPriority}`;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user