dynamic initials
This commit is contained in:
parent
b7f3d6a858
commit
2b61fbac96
10 changed files with 153 additions and 109 deletions
|
|
@ -19,7 +19,9 @@
|
|||
<router-view/>
|
||||
|
||||
</div>
|
||||
|
||||
<Splash v-else />
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { ipcMain } from "electron";
|
|||
import { play } from './audio';
|
||||
|
||||
import {
|
||||
AuthMessage,
|
||||
Creds,
|
||||
Profile,
|
||||
Annotation,
|
||||
StandardMessage,
|
||||
|
|
@ -22,7 +22,7 @@ let socket: WebSocket;
|
|||
let success = false;
|
||||
let auth = false;
|
||||
|
||||
const onAuthSession = async (e: any, payload: string | null): Promise<string> => {
|
||||
const onAuthSession = async (e: any, payload: string | Creds) => {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
|
|
@ -41,13 +41,13 @@ const onAuthSession = async (e: any, payload: string | null): Promise<string> =>
|
|||
|
||||
});
|
||||
|
||||
// payload == token
|
||||
if (payload) {
|
||||
socket.send(payload);
|
||||
} else {
|
||||
socket.send("no-token");
|
||||
if (typeof payload !== "string") {
|
||||
payload = JSON.stringify(payload)
|
||||
}
|
||||
|
||||
// Send token to backend
|
||||
socket.send(payload);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -59,9 +59,10 @@ const handleAuthMessage = (message: string) => {
|
|||
}
|
||||
|
||||
const handleProfileMessage = (message: Profile) => {
|
||||
console.log("Updating profile...")
|
||||
backgroundMitt.emit('ipc-renderer', {
|
||||
endpoint: 'update-profile',
|
||||
message: message
|
||||
message: message
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -85,6 +86,7 @@ const handleStandardMessage = (m: StandardMessage) => {
|
|||
}
|
||||
|
||||
const handleAnnotationMessage = (message: Annotation) => {
|
||||
console.log("Annotation message")
|
||||
backgroundMitt.emit('ipc-renderer', {
|
||||
endpoint: 'annotate-message',
|
||||
message: message
|
||||
|
|
|
|||
|
|
@ -101,7 +101,6 @@ export default function useTextInputController(elementX: Ref) {
|
|||
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
const key = keyboardNameMap[e.keyCode]
|
||||
console.log(key)
|
||||
|
||||
if (textInput) {
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@
|
|||
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent, ref, onMounted } from "vue";
|
||||
import { defineComponent, ref, onMounted, onUnmounted } from "vue";
|
||||
import draggify from "@/modules/draggify";
|
||||
|
||||
import { Profile } from "@/types/message/index";
|
||||
|
||||
import TextInput from "@/components/inputItem/textInput.vue";
|
||||
import useTextInputController from
|
||||
"@/components/inputItem/controllers/textCtrl";
|
||||
|
|
@ -42,7 +40,7 @@ export default defineComponent({
|
|||
setup() {
|
||||
|
||||
// Mark input item with user's initials.
|
||||
let initials = ref("")
|
||||
const initials = ref("")
|
||||
initials.value = "IN";
|
||||
|
||||
// Initial position.
|
||||
|
|
@ -60,19 +58,23 @@ export default defineComponent({
|
|||
const { recording } = useAudioInputController(typing)
|
||||
|
||||
// Update profile functionality.
|
||||
const onUpdateProfile = (_event: any, payload: Profile) => {
|
||||
window.localStorage.setItem("profile", JSON.stringify(payload));
|
||||
initials.value = payload.first[0] + payload.last[0]
|
||||
const onUpdateProfile = (_event: any, payload: any) => {
|
||||
initials.value = payload.message.first[0] + payload.message.last[0]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.ipcRenderer.on("update-profile", onUpdateProfile);
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.ipcRenderer.removeAllListeners("update-profile");
|
||||
})
|
||||
|
||||
return {
|
||||
elementX,
|
||||
elementY,
|
||||
recording
|
||||
recording,
|
||||
initials
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ const authToken = async () => {
|
|||
const { invoke } = useIpc();
|
||||
try {
|
||||
token = window.localStorage.getItem(AUTH_KEY);
|
||||
|
||||
if (!token) {
|
||||
token = "no-token"
|
||||
}
|
||||
|
||||
console.log(`Token ${token}`)
|
||||
const res = await invoke('auth-session', token);
|
||||
window.localStorage.setItem(AUTH_KEY, res);
|
||||
state.accessToken = res;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { ref } from 'vue';
|
||||
import useScroll from "@/modules/scroll";
|
||||
import { RenderMessage, Annotation } from "@/types/message/index";
|
||||
|
||||
const messagesKey = "CRIMATA_MESSAGES";
|
||||
|
|
@ -7,7 +8,7 @@ const sizeLimit = 200;
|
|||
// list of messages where the first item is the oldest message.
|
||||
const messages = ref(new Map());
|
||||
|
||||
// get stored messages.
|
||||
// Get stored messages.
|
||||
const messagesString = window.localStorage.getItem(messagesKey);
|
||||
|
||||
if (messagesString) {
|
||||
|
|
@ -17,51 +18,75 @@ if (messagesString) {
|
|||
messages.value = new Map(Object.entries(parsed));
|
||||
}
|
||||
|
||||
// utility function to remove oldest message from the messages map.
|
||||
// Remove oldest message from the messages map.
|
||||
function deleteOldest() {
|
||||
// create array of map keys and get the key of the oldest message.
|
||||
const lastKey = Array.from(messages.value.keys()).shift();
|
||||
|
||||
messages.value.delete(lastKey);
|
||||
}
|
||||
|
||||
// Is the message div scrolled to the bottom?
|
||||
let isScrolledToBottom: boolean;
|
||||
//---Message Grouping-----------------------------------------------
|
||||
|
||||
// Update isScrolledToBottom
|
||||
const updateScrollRef = () => {
|
||||
const e = document.getElementById("messenger")
|
||||
if (e) {
|
||||
isScrolledToBottom = e.scrollHeight - e.clientHeight <= e.scrollTop + 1
|
||||
}
|
||||
}
|
||||
let prevRef: string;
|
||||
let activeGroup = false;
|
||||
|
||||
// Adjust scroll after we add content to the messenger.
|
||||
const adjustScroll = () => {
|
||||
const e = document.getElementById("messenger")
|
||||
if (e) {
|
||||
if (isScrolledToBottom) {
|
||||
e.scrollTo({
|
||||
top: e.scrollHeight - e.clientHeight,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
const updateGrouping = (currentMessageRef: string) => {
|
||||
if (prevRef) {
|
||||
|
||||
// Get references to the two most recent messages.
|
||||
const prev = messages.value.get(prevRef)
|
||||
const current = messages.value.get(currentMessageRef)
|
||||
|
||||
// See if they should be grouped.
|
||||
if (current.time < prev.time + 20000) {
|
||||
if (prev.modifier === current.modifier) {
|
||||
if (prev.context === current.context) {
|
||||
|
||||
// Update grouping accordingly.
|
||||
if (activeGroup) {
|
||||
prev.isChild = "middle";
|
||||
}
|
||||
|
||||
else {
|
||||
prev.isChild = "first";
|
||||
}
|
||||
|
||||
current.isChild = "last";
|
||||
activeGroup = true;
|
||||
}
|
||||
|
||||
// If messages unrealated, reset activeGroup.
|
||||
else {
|
||||
activeGroup = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prevRef = currentMessageRef;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
||||
export default function useMessages() {
|
||||
|
||||
const addMessage = (m: RenderMessage) => {
|
||||
updateScrollRef() // must update before we add new elements.
|
||||
// Control the scrolling.
|
||||
const { updateScrollRef, adjustScroll } = useScroll("messenger");
|
||||
|
||||
// check for message limit before setting a new message.
|
||||
if (messages.value.size >= sizeLimit) deleteOldest();
|
||||
// Add a new message to the view.
|
||||
const addMessage = (message: RenderMessage) => {
|
||||
updateScrollRef()
|
||||
|
||||
messages.value.set(m.uid, m);
|
||||
if (messages.value.size >= sizeLimit) {
|
||||
deleteOldest();
|
||||
}
|
||||
|
||||
setTimeout(adjustScroll, 10);
|
||||
messages.value.set(message.uid, message);
|
||||
|
||||
setTimeout(adjustScroll, 20);
|
||||
updateGrouping(message.uid)
|
||||
}
|
||||
|
||||
// Update an existing message in the view.
|
||||
const updateMessage = (a: Annotation) => {
|
||||
updateScrollRef()
|
||||
|
||||
|
|
@ -70,14 +95,10 @@ export default function useMessages() {
|
|||
message.context = a.context
|
||||
message.content.text = a.text
|
||||
|
||||
setTimeout(adjustScroll, 10);
|
||||
|
||||
console.log(`Annotation: ${a.text}`)
|
||||
console.log(`Annotation: ${a.context}`)
|
||||
|
||||
return message
|
||||
setTimeout(adjustScroll, 20);
|
||||
}
|
||||
|
||||
// Used in App.vue on shutdown.
|
||||
const saveMessages = () => {
|
||||
// de-reactivate message data before saving.
|
||||
const messageData = Object.fromEntries(messages.value);
|
||||
|
|
|
|||
37
src/modules/scroll.ts
Normal file
37
src/modules/scroll.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
|
||||
export default function useScroll(element: string) {
|
||||
|
||||
let isScrolledToBottom: boolean;
|
||||
|
||||
// Update isScrolledToBottom
|
||||
const updateScrollRef = () => {
|
||||
const view = document.getElementById(element)
|
||||
|
||||
if (view) {
|
||||
isScrolledToBottom = view.scrollHeight - view.clientHeight <= view.scrollTop + 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Adjust scroll after we add content to the messenger.
|
||||
const adjustScroll = () => {
|
||||
const view = document.getElementById(element)
|
||||
|
||||
if (view) {
|
||||
if (isScrolledToBottom) {
|
||||
view.scrollTo({
|
||||
top: view.scrollHeight - view.clientHeight,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
updateScrollRef,
|
||||
adjustScroll
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,15 +16,22 @@ export interface ClientMessage {
|
|||
uid: string;
|
||||
}
|
||||
|
||||
// Possible messages from server:
|
||||
|
||||
export interface AuthMessage {
|
||||
key: string;
|
||||
export interface Creds {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
// Possible messages from server:
|
||||
|
||||
export interface Profile {
|
||||
crimata_id: string;
|
||||
title: string;
|
||||
first: string;
|
||||
middle: string;
|
||||
last: string;
|
||||
suffix: string | number;
|
||||
nickname: string;
|
||||
full: string;
|
||||
}
|
||||
|
||||
export interface Annotation {
|
||||
|
|
|
|||
|
|
@ -36,45 +36,46 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent, ref } from "vue";
|
||||
import { useAuth } from "@/modules/auth";
|
||||
import { useIpc } from "@/modules/ipc";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
interface LoginPayload {
|
||||
email: string;
|
||||
password: string;
|
||||
rememberMe: boolean;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: "Login",
|
||||
|
||||
setup() {
|
||||
|
||||
const { setToken } = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
const email = ref("");
|
||||
const password = ref("");
|
||||
const rememberMe = ref(true);
|
||||
const invalid = ref(false);
|
||||
|
||||
const { invoke } = useIpc();
|
||||
|
||||
const submit = async () => {
|
||||
|
||||
const payload = {
|
||||
request: "login",
|
||||
email: email.value,
|
||||
password: password.value
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await invoke('auth-session', payload);
|
||||
setToken(res);
|
||||
invalid.value = false;
|
||||
router.push({ name: "home" });
|
||||
} catch(e){
|
||||
}
|
||||
|
||||
catch(e) {
|
||||
invalid.value = true;
|
||||
console.log('Error loging in.');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const switchView = () => {
|
||||
|
|
@ -85,10 +86,10 @@ export default defineComponent({
|
|||
submit,
|
||||
email,
|
||||
password,
|
||||
rememberMe,
|
||||
switchView,
|
||||
invalid
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -28,55 +28,20 @@ export default defineComponent({
|
|||
},
|
||||
setup() {
|
||||
|
||||
// Listen for self-messages from inputItem.
|
||||
const { emitter } = useMitt();
|
||||
|
||||
// Handle messages in view.
|
||||
const { messages, addMessage, updateMessage } = useMessages();
|
||||
|
||||
let prevRef: string; // ref to previous message
|
||||
let activeGroup = false; // if active group exists.
|
||||
// Alter existing message.
|
||||
const onAnnotateMessage = (_event: any, payload: any) => {
|
||||
updateMessage(payload.message);
|
||||
}
|
||||
|
||||
// When backend has new message.
|
||||
// Render new message.
|
||||
const onRenderMessage = (_event: any, payload: any) => {
|
||||
let message = payload.message; // cleaner
|
||||
|
||||
// Check type and handle accordingly.
|
||||
if (message.content) {
|
||||
addMessage(message);
|
||||
} else {
|
||||
message = updateMessage(message);
|
||||
}
|
||||
|
||||
// Check for grouping.
|
||||
if (prevRef) {
|
||||
const prev = messages.value.get(prevRef)
|
||||
const current = messages.value.get(message.uid)
|
||||
|
||||
console.log(`${message.modifier}, ${prev.modifier}`)
|
||||
console.log(`${message.context}, ${prev.context}`)
|
||||
|
||||
// If last two messages go together...group accordingly.
|
||||
if (current.time < prev.time + 20000 && current.modifier === prev.modifier && current.context === prev.context) {
|
||||
|
||||
if (activeGroup) {
|
||||
prev.isChild = "middle"
|
||||
} else {
|
||||
prev.isChild = "first"
|
||||
}
|
||||
|
||||
// Current always last child.
|
||||
current.isChild = "last"
|
||||
activeGroup = true
|
||||
}
|
||||
|
||||
// Else...reset activeGroup.
|
||||
else {
|
||||
activeGroup = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Set previous message for next time.
|
||||
prevRef = message.uid
|
||||
|
||||
addMessage(payload.message);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
@ -86,11 +51,13 @@ export default defineComponent({
|
|||
|
||||
// Back end listener.
|
||||
window.ipcRenderer.on("render-message", onRenderMessage);
|
||||
window.ipcRenderer.on("annotate-message", onAnnotateMessage);
|
||||
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.ipcRenderer.removeAllListeners("render-message");
|
||||
window.ipcRenderer.removeAllListeners("annotate-message");
|
||||
emitter.all.clear();
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue