Mostly have live scrolling working.

This commit is contained in:
Ryan Pandya 2023-05-10 01:14:29 -07:00
parent 994b26b2bd
commit 8239a096c8
5 changed files with 129 additions and 14 deletions

View File

@ -12,6 +12,7 @@
"appwrite": "^11.0.0", "appwrite": "^11.0.0",
"axios": "^1.4.0", "axios": "^1.4.0",
"handsontable": "^12.3.3", "handsontable": "^12.3.3",
"luxon": "^3.3.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"node": "^20.0.0", "node": "^20.0.0",
"pinia": "^2.0.35", "pinia": "^2.0.35",
@ -1295,6 +1296,14 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/luxon": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
"integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==",
"engines": {
"node": ">=12"
}
},
"node_modules/magic-string": { "node_modules/magic-string": {
"version": "0.25.9", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
@ -3196,6 +3205,11 @@
"yallist": "^4.0.0" "yallist": "^4.0.0"
} }
}, },
"luxon": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
"integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg=="
},
"magic-string": { "magic-string": {
"version": "0.25.9", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",

View File

@ -14,6 +14,7 @@
"appwrite": "^11.0.0", "appwrite": "^11.0.0",
"axios": "^1.4.0", "axios": "^1.4.0",
"handsontable": "^12.3.3", "handsontable": "^12.3.3",
"luxon": "^3.3.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"node": "^20.0.0", "node": "^20.0.0",
"pinia": "^2.0.35", "pinia": "^2.0.35",

View File

@ -21,6 +21,14 @@
filter: contrast(85%); filter: contrast(85%);
} }
.invert {
filter: invert();
}
.day-of-week{
text-transform: uppercase;
}
.handsontable * { .handsontable * {
border: 0px !important; border: 0px !important;
text-align: center !important; text-align: center !important;

View File

@ -1,4 +1,5 @@
import { Client, Databases, Account, Query } from "appwrite"; import { Client, Databases, Account, Query } from "appwrite";
import { DateTime } from "luxon";
class AppwriteService { class AppwriteService {
databaseId = 'lifetracker-db'; databaseId = 'lifetracker-db';
@ -40,12 +41,25 @@ class AppwriteService {
return await this.getUser(); return await this.getUser();
} }
getEntries = async () => { getEntries = async (date=null, numEntries=25) => {
if(date == null){date = DateTime.now()}
date = DateTime.fromISO(date);
var firstEntry = (await this.database.listDocuments(
this.databaseId, this.collectionId,
[Query.orderAsc("date"),Query.limit(1)])
).documents[0];
var referenceDate = DateTime.fromISO(firstEntry.date).toUTC();
var offset = Math.floor(date.diff(referenceDate).as("days")) - 1;
return (await this.database.listDocuments( return (await this.database.listDocuments(
this.databaseId, this.collectionId, this.databaseId, this.collectionId,
[ [
Query.orderAsc("date"), Query.orderAsc("date"),
//Query.limit(365) Query.offset(offset),
Query.limit(numEntries)
] ]
) )
).documents; ).documents;

View File

@ -2,11 +2,11 @@
import { useDatabaseStore } from "@/stores/database" import { useDatabaseStore } from "@/stores/database"
import Api from "@/services/Api" import Api from "@/services/Api"
import appwrite from '@/services/appwrite'; import appwrite from '@/services/appwrite';
import moment from 'moment'; import { DateTime } from "luxon";
</script> </script>
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent, toRaw, reactive } from 'vue';
import { HotTable } from '@handsontable/vue3'; import { HotTable } from '@handsontable/vue3';
import { registerAllModules } from 'handsontable/registry'; import { registerAllModules } from 'handsontable/registry';
import 'handsontable/dist/handsontable.full.css'; import 'handsontable/dist/handsontable.full.css';
@ -15,6 +15,21 @@ import Handsontable from 'handsontable/base';
// register Handsontable's modules // register Handsontable's modules
registerAllModules(); registerAllModules();
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function getHourClass(i) { function getHourClass(i) {
const colorMapping = { const colorMapping = {
0: "black", 0: "black",
@ -29,6 +44,9 @@ function getHourClass(i) {
9: "darkred", 9: "darkred",
10: "lime" 10: "lime"
} }
if(i > 10){
i = Math.round(i/10) - 1
}
if (i == null) { if (i == null) {
return ""; return "";
} }
@ -58,14 +76,21 @@ const ExampleComponent = defineComponent({
data() { data() {
return { return {
entries: [], entries: [],
numEntries: 25,
offset: 0,
hotSettings: { hotSettings: {
autoRowSize: true,
columns: [ columns: [
{ {
readOnly: true, readOnly: true,
data: "date", data: "date",
renderer(instance, td, row, col, prop, value) { renderer(instance, td, row, col, prop, value) {
var date = new moment(value).utc().format("MM/DD"); var date = DateTime.fromISO(value).toUTC().toFormat("MM/dd");
td.className = "color-black"; var today = DateTime.now().toFormat("MM/dd");
if(today == date){
td.className = "color-black invert";
}
else{td.className = "color-black";}
td.innerText = date; td.innerText = date;
return td; return td;
} }
@ -74,8 +99,13 @@ const ExampleComponent = defineComponent({
readOnly: true, readOnly: true,
data: "date", data: "date",
renderer(instance, td, row, col, prop, value) { renderer(instance, td, row, col, prop, value) {
var date = new moment(value).utc().format("ddd") var date = DateTime.fromISO(value).toUTC();
td.innerText = date; var today = DateTime.now().toFormat("MM/dd");
if(date.toFormat("MM/dd") == today){
td.className = "color-black invert day-of-week";
}
else{td.className = "color-black day-of-week";}
td.innerText = date.toFormat("EEE");
return td; return td;
} }
}, },
@ -91,7 +121,7 @@ const ExampleComponent = defineComponent({
rowHeights: '22px', rowHeights: '22px',
colWidths(i) { colWidths(i) {
if((i > 1) && (i < 26)){ if((i > 1) && (i < 26)){
return "40px"; return "50px";
} }
else if(i == 27){ else if(i == 27){
return "1000px"; return "1000px";
@ -105,6 +135,7 @@ const ExampleComponent = defineComponent({
}, },
afterChange: (changes) => { afterChange: (changes) => {
this.fixSelectionBug(); this.fixSelectionBug();
//this.setActiveHourHeader();
if (changes != null) { if (changes != null) {
var entry = this.entries[changes[0][0]]; var entry = this.entries[changes[0][0]];
entry.date = entry.date.replace(/T.*/, ""); entry.date = entry.date.replace(/T.*/, "");
@ -118,22 +149,67 @@ const ExampleComponent = defineComponent({
}, },
async mounted(){ async mounted(){
this.user = await appwrite.getUser(); this.user = await appwrite.getUser();
this.entries = await appwrite.getEntries(); this.entries = await appwrite.getEntries(null,5);
this.updateTable(); this.updateTable();
this.subscribe(); this.subscribe();
this.fixSelectionBug(); this.fixSelectionBug();
}, },
created () {
window.addEventListener('wheel', debounce(this.handleScroll, 300, true));
},
unmounted () {
window.removeEventListener('wheel', debounce(this.handleScroll, 300, true));
},
methods: { methods: {
setActiveHourHeader(){
var timeString = DateTime.now().toFormat("hh a");
var currentTimeHeader = Array.from(document.querySelectorAll("th"))
.find(el => el.innerText == timeString);
currentTimeHeader.className = "invert";
},
async handleScroll(e){
var offset;
if(e.deltaY > 0){
var lastDate = DateTime.fromISO(
this.entries[
this.hotRef
.getPlugin('autoRowSize')
.getLastVisibleRow()
].date).toUTC().plus({ days: 1 });
console.log("Grabbing 5 more entries starting at " + lastDate.toISO());
var newEntries = await appwrite.getEntries(
lastDate.plus({ days: 1 })
, 5);
newEntries.forEach((e) => {
this.entries.push(e);
})
}
else{
var firstDate = DateTime.fromISO(
this.entries[
this.hotRef
.getPlugin('autoRowSize')
.getFirstVisibleRow()
].date).toUTC().minus({ days: 1 });
console.log("Grabbing 5 previous entries ending at " + firstDate.toISO());
var newEntries = await appwrite.getEntries(
firstDate.minus({ days: 6 })
, 5);
var entries = this.entries;
newEntries.reverse().forEach((e) => {
entries.unshift(e);
})
this.entries = entries;
}
},
fixSelectionBug(){ fixSelectionBug(){
if(this.hotRef){ if(this.hotRef){
var offset = (this.hotRef.getRowHeight() + 1) * this.entries.length;//document.querySelector(".wtHider").clientHeight; var offset = (this.hotRef.getRowHeight()) * (this.entries.length + 1) + 2;//document.querySelector(".wtHider").clientHeight;
document.querySelector(".htBorders div").style.top = "-" + offset + "px"; document.querySelector(".htBorders div").style.top = "-" + offset + "px";
} }
}, },
subscribe(){ subscribe(){
console.log("subscribing");
appwrite.subscribe((payload) => { appwrite.subscribe((payload) => {
console.log("Caught " + payload);
var event = payload.events.filter((e) => var event = payload.events.filter((e) =>
e.match(/databases\.\*\.collections\.\*\.documents\.\*\.\w+/) e.match(/databases\.\*\.collections\.\*\.documents\.\*\.\w+/)
)[0].replace(/.+\./,""); )[0].replace(/.+\./,"");
@ -172,7 +248,9 @@ export default ExampleComponent;
</script> </script>
<template> <template>
<!-- <button @click="updateTable">Fetch</button> <button @click="concatEntries">Fuck</button>
<!-- <div>{{ entries }}</div>
<ul> <ul>
<li v-for="e in entries" :key="e"> <li v-for="e in entries" :key="e">
{{ e }} {{ e }}