<router-view/>
</div>
+
<Splash v-else />
+
</template>
<script lang="ts">
import { play } from './audio';
import {
- AuthMessage,
+ Creds,
Profile,
Annotation,
StandardMessage,
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) => {
});
- // 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);
+
});
};
}
const handleProfileMessage = (message: Profile) => {
+ console.log("Updating profile...")
backgroundMitt.emit('ipc-renderer', {
endpoint: 'update-profile',
- message: message
+ message: message
});
}
}
const handleAnnotationMessage = (message: Annotation) => {
+ console.log("Annotation message")
backgroundMitt.emit('ipc-renderer', {
endpoint: 'annotate-message',
message: message
const onKeyDown = (e: KeyboardEvent) => {
const key = keyboardNameMap[e.keyCode]
- console.log(key)
if (textInput) {
<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";
setup() {
// Mark input item with user's initials.
- let initials = ref("")
+ const initials = ref("")
initials.value = "IN";
// Initial position.
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
};
},
});
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;
import { ref } from 'vue';
+import useScroll from "@/modules/scroll";
import { RenderMessage, Annotation } from "@/types/message/index";
const messagesKey = "CRIMATA_MESSAGES";
// 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) {
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;
+
+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";
+ }
-// 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'
- });
+ 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()
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);
--- /dev/null
+
+
+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
+ }
+
+}
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 {
</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 = () => {
submit,
email,
password,
- rememberMe,
switchView,
invalid
- };
+ }
+
},
});
</script>
},
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(() => {
// 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();
});