use ms timestamps everywhere

This commit is contained in:
Nikita Galaiko 2023-02-20 12:41:01 +01:00
parent bd2c5b5809
commit 2e0f757cd9
No known key found for this signature in database
GPG Key ID: EBAB54E845BA519D
16 changed files with 72 additions and 64 deletions

View File

@ -20,7 +20,7 @@ tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-works
tauri-plugin-log = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev", features = ["colored"] }
log = "0.4.17"
notify = "5.1.0"
serde_json = "1.0.92"
serde_json = {version = "1.0.92", features = [ "std", "arbitrary_precision" ] }
uuid = "1.3.0"
yrs = "0.16.1"
difference = "2.0.0"

View File

@ -8,7 +8,7 @@ use std::{collections::HashMap, path::Path};
#[serde(rename_all = "camelCase")]
pub struct Delta {
pub operations: Vec<operations::Operation>,
pub timestamp_ms: u64,
pub timestamp_ms: u128,
}
pub fn read(project: &projects::Project, file_path: &Path) -> Result<Option<Vec<Delta>>> {

View File

@ -68,7 +68,7 @@ impl TextDocument {
timestamp_ms: SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis() as u64,
.as_millis(),
};
if event.operations.len() == 0 {
return false;

View File

@ -6,7 +6,7 @@ use serde::Serialize;
pub struct Activity {
#[serde(rename = "type")]
pub activity_type: String,
pub timestamp: u64,
pub timestamp_ms: u128,
pub message: String,
}
@ -14,13 +14,13 @@ pub fn parse_reflog_line(line: &str) -> Result<Activity> {
match line.split("\t").collect::<Vec<&str>>()[..] {
[meta, message] => {
let meta_parts = meta.split_whitespace().collect::<Vec<&str>>();
let timestamp = meta_parts[meta_parts.len() - 2].parse::<u64>()?;
let timestamp_ms = meta_parts[meta_parts.len() - 2].parse::<u128>()?;
match message.split(": ").collect::<Vec<&str>>()[..] {
[entry_type, msg] => Ok(Activity {
activity_type: entry_type.to_string(),
message: msg.to_string(),
timestamp,
timestamp_ms,
}),
_ => Err(anyhow!("failed to parse reflog line: {}", line)),
}

View File

@ -5,39 +5,39 @@ fn test_parse_reflog_line() {
let test_cases = vec![
(
"9ea641990993cb60c7d89c41606f6b457adb9681 3f2657e0d1eae57f58d7734aae10310a861de8e8 Nikita Galaiko <nikita@galaiko.rocks> 1676275740 +0100 commit: try sturdy mac dev certificate",
Activity{ activity_type: "commit".to_string(), timestamp: 1676275740, message: "try sturdy mac dev certificate".to_string() }
Activity{ activity_type: "commit".to_string(), timestamp_ms: 1676275740000, message: "try sturdy mac dev certificate".to_string() }
),
(
"999bc2f0194ea001f71ba65b5422a742b5e66d9f bb98b5411d597fdede63053c190260a38d459ecb Nikita Galaiko <nikita@galaiko.rocks> 1675428111 +0100 checkout: moving from production-build to master",
Activity{ activity_type: "checkout".to_string(), timestamp: 1675428111, message: "moving from production-build to master".to_string() },
Activity{ activity_type: "checkout".to_string(), timestamp_ms: 1675428111000, message: "moving from production-build to master".to_string() },
),
(
"0000000000000000000000000000000000000000 9aa96f488fbdb8f7b15151d9d2e47690d3b21b46 Nikita Galaiko <nikita@galaiko.rocks> 1675176957 +0100 commit (initial): simple tauri example",
Activity{ activity_type: "commit (initial)".to_string(), timestamp: 1675176957, message: "simple tauri example".to_string() },
Activity{ activity_type: "commit (initial)".to_string(), timestamp_ms: 1675176957000, message: "simple tauri example".to_string() },
),
(
"d083bb9213fc5e0bb6d07c2c6c1eae5be483be25 dc870a80fddb843583baa36cb637c5c820b1e863 Nikita Galaiko <nikita@galaiko.rocks> 1675425613 +0100 commit (amend): build app with github actions",
Activity{ activity_type: "commit (amend)".to_string(), timestamp: 1675425613, message: "build app with github actions".to_string() },
Activity{ activity_type: "commit (amend)".to_string(), timestamp_ms: 1675425613000, message: "build app with github actions".to_string() },
),
(
"2843be38a72ac8418c7e5c5630cba3c4803916d1 fbb7a9356484b948bde4c7ee9fdeb6439edff8c0 Nikita Galaiko <nikita@galaiko.rocks> 1676274883 +0100 pull: Fast-forward",
Activity{ activity_type: "pull".to_string(), timestamp: 1676274883, message: "Fast-forward".to_string() },
Activity{ activity_type: "pull".to_string(), timestamp_ms: 1676274883000, message: "Fast-forward".to_string() },
),
(
"3f2657e0d1eae57f58d7734aae10310a861de8e8 3f2657e0d1eae57f58d7734aae10310a861de8e8 Nikita Galaiko <nikita@galaiko.rocks> 1676277401 +0100 reset: moving to HEAD",
Activity{ activity_type: "reset".to_string() , timestamp: 1676277401, message: "moving to HEAD".to_string() },
Activity{ activity_type: "reset".to_string() , timestamp_ms: 1676277401000, message: "moving to HEAD".to_string() },
),
(
"9a831ba2fa07aa6a399bbb498e8effd913cec2e0 add94e65594e4c240b0f6b03973a3be3ff594306 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (start): checkout add94e65594e4c240b0f6b03973a3be3ff594306",
Activity{ activity_type: "pull --rebase (start)".to_string(), timestamp: 1676039997, message: "checkout add94e65594e4c240b0f6b03973a3be3ff594306".to_string() },
Activity{ activity_type: "pull --rebase (start)".to_string(), timestamp_ms: 1676039997000, message: "checkout add94e65594e4c240b0f6b03973a3be3ff594306".to_string() },
),
(
"add94e65594e4c240b0f6b03973a3be3ff594306 bcc93167c068649868aa3df4999ba154468a62b5 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (pick): make app run in background",
Activity{ activity_type: "pull --rebase (pick)".to_string(), timestamp: 1676039997, message: "make app run in background".to_string() },
Activity{ activity_type: "pull --rebase (pick)".to_string(), timestamp_ms: 1676039997000, message: "make app run in background".to_string() },
),
(
"bcc93167c068649868aa3df4999ba154468a62b5 bcc93167c068649868aa3df4999ba154468a62b5 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (finish): returning to refs/heads/master",
Activity{ activity_type: "pull --rebase (finish)".to_string(), timestamp: 1676039997, message: "returning to refs/heads/master".to_string() },
Activity{ activity_type: "pull --rebase (finish)".to_string(), timestamp_ms: 1676039997000, message: "returning to refs/heads/master".to_string() },
)
];

View File

@ -18,9 +18,9 @@ use uuid::Uuid;
#[serde(rename_all = "camelCase")]
pub struct Meta {
// timestamp of when the session was created
pub start_ts: u64,
pub start_timestamp_ms: u128,
// timestamp of when the session was last active
pub last_ts: u64,
pub last_timestamp_ms: u128,
// session branch name
pub branch: String,
// session commit hash
@ -47,7 +47,7 @@ impl Session {
let start_path = meta_path.join("start");
let start_ts = std::fs::read_to_string(start_path.clone())?
.parse::<u64>()
.parse::<u128>()
.with_context(|| {
format!(
"failed to parse start timestamp from {}",
@ -57,7 +57,7 @@ impl Session {
let last_path = meta_path.join("last");
let last_ts = std::fs::read_to_string(last_path.clone())?
.parse::<u64>()
.parse::<u128>()
.with_context(|| {
format!(
"failed to parse last timestamp from {}",
@ -84,7 +84,7 @@ impl Session {
let activity = reflog
.lines()
.filter_map(|line| activity::parse_reflog_line(line).ok())
.filter(|activity| activity.timestamp >= start_ts)
.filter(|activity| activity.timestamp_ms >= start_ts)
.collect::<Vec<activity::Activity>>();
let id_path = meta_path.join("id");
@ -96,8 +96,8 @@ impl Session {
hash: None,
activity,
meta: Meta {
start_ts,
last_ts,
start_timestamp_ms: start_ts,
last_timestamp_ms: last_ts,
branch,
commit,
},
@ -108,15 +108,15 @@ impl Session {
let now_ts = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
.as_millis();
let head = repo.head()?;
let session = Session {
id: Uuid::new_v4().to_string(),
hash: None,
meta: Meta {
start_ts: now_ts,
last_ts: now_ts,
start_timestamp_ms: now_ts,
last_timestamp_ms: now_ts,
branch: head.name().unwrap().to_string(),
commit: head.peel_to_commit().unwrap().id().to_string(),
},
@ -131,8 +131,8 @@ impl Session {
format!("failed to get tree from commit {}", commit.id().to_string())
})?;
let start_ts = read_as_string(repo, &tree, Path::new("session/meta/start"))?
.parse::<u64>()
let start_timestamp_ms = read_as_string(repo, &tree, Path::new("session/meta/start"))?
.parse::<u128>()
.with_context(|| {
format!(
"failed to parse start timestamp from commit {}",
@ -149,7 +149,7 @@ impl Session {
let activity = reflog
.lines()
.filter_map(|line| activity::parse_reflog_line(line).ok())
.filter(|activity| activity.timestamp >= start_ts)
.filter(|activity| activity.timestamp_ms >= start_timestamp_ms)
.collect::<Vec<activity::Activity>>();
Ok(Session {
@ -161,9 +161,9 @@ impl Session {
})?,
hash: Some(commit.id().to_string()),
meta: Meta {
start_ts,
last_ts: read_as_string(repo, &tree, Path::new("session/meta/last"))?
.parse::<u64>()
start_timestamp_ms,
last_timestamp_ms: read_as_string(repo, &tree, Path::new("session/meta/last"))?
.parse::<u128>()
.with_context(|| {
format!(
"failed to parse last timestamp from commit {}",
@ -222,7 +222,11 @@ fn write(session_path: &Path, session: &Session) -> Result<()> {
.with_context(|| format!("failed to write session id to {}", id_path.display()))?;
let start_path = meta_path.join("start");
std::fs::write(start_path.clone(), session.meta.start_ts.to_string()).with_context(|| {
std::fs::write(
start_path.clone(),
session.meta.start_timestamp_ms.to_string(),
)
.with_context(|| {
format!(
"failed to write session start timestamp to {}",
start_path.display()
@ -230,7 +234,11 @@ fn write(session_path: &Path, session: &Session) -> Result<()> {
})?;
let last_path = meta_path.join("last");
std::fs::write(last_path.clone(), session.meta.last_ts.to_string()).with_context(|| {
std::fs::write(
last_path.clone(),
session.meta.last_timestamp_ms.to_string(),
)
.with_context(|| {
format!(
"failed to write session last timestamp to {}",
last_path.display()

View File

@ -237,8 +237,8 @@ fn write_beginning_meta_files<R: tauri::Runtime>(
let now_ts = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
session.meta.last_ts = now_ts;
.as_millis();
session.meta.last_timestamp_ms = now_ts;
session
.update(project)
.with_context(|| "failed to update session")?;

View File

@ -6,8 +6,8 @@ use std::{
time::{Duration, SystemTime},
};
const FIVE_MINUTES: u64 = Duration::new(5 * 60, 0).as_secs();
const ONE_HOUR: u64 = Duration::new(60 * 60, 0).as_secs();
const FIVE_MINUTES: u128 = Duration::new(5 * 60, 0).as_millis();
const ONE_HOUR: u128 = Duration::new(60 * 60, 0).as_millis();
#[derive(Debug, Clone)]
pub struct GitWatcher {
@ -124,10 +124,10 @@ fn session_to_commit(
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs() as u64;
.as_millis();
let elapsed_last = now - current_session.meta.last_ts;
let elapsed_start = now - current_session.meta.start_ts;
let elapsed_last = now - current_session.meta.last_timestamp_ms;
let elapsed_start = now - current_session.meta.start_timestamp_ms;
// TODO: uncomment
if (elapsed_last > FIVE_MINUTES) || (elapsed_start > ONE_HOUR) {

View File

@ -35,8 +35,8 @@
class="hover:text-zinc-200"
href="/projects/{$project.id}/sessions/{$session.id}"
>
{toHumanReadableTime($session.meta.startTs)}
{toHumanReadableTime($session.meta.lastTs)}
{toHumanReadableTime($session.meta.startTimestampMs)}
{toHumanReadableTime($session.meta.lastTimestampMs)}
</a>
{/if}
</div>

View File

@ -19,14 +19,14 @@
</div>
<div class="mt-1 text-xs">
<span>
{#if session.meta.startTs}
{toHumanReadableTime(session.meta.startTs)}
{#if session.meta.startTimestampMs}
{toHumanReadableTime(session.meta.startTimestampMs)}
{/if}
</span>
<span></span>
<span>
{#if session.meta.lastTs}
{toHumanReadableTime(session.meta.lastTs)}
{#if session.meta.lastTimestampMs}
{toHumanReadableTime(session.meta.lastTimestampMs)}
{/if}
</span>
</div>

View File

@ -63,16 +63,16 @@
<div class="my-2 mx-1">
<TimelineDaySessionActivities
activities={session.activity}
sessionStart={session.meta.startTs}
sessionEnd={session.meta.lastTs}
sessionStart={session.meta.startTimestampMs}
sessionEnd={session.meta.lastTimestampMs}
/>
</div>
</div>
<div id="time-range" class="text-xs">
{toHumanReadableDate(session.meta.startTs)},
{toHumanReadableTime(session.meta.startTs)}
{toHumanReadableDate(session.meta.startTimestampMs)},
{toHumanReadableTime(session.meta.startTimestampMs)}
<div class="text-xs text-zinc-600">
{Math.round((session.meta.lastTs - session.meta.startTs) / 60)} min
{Math.round((session.meta.lastTimestampMs - session.meta.startTimestampMs) / 60)} min
</div>
</div>
<div id="files">

View File

@ -29,14 +29,14 @@
<div
class="flex -mx-1.5"
style="position:relative; left: {proportionOfTime(
activity.timestamp
activity.timestampMs
)}%;"
>
<div
class="w-3 h-3 text-slate-700 z-50 absolute inset-0"
style=""
title="{activity.type}: {activity.message} at {toHumanReadableTime(
activity.timestamp
activity.timestampMs
)}"
>
{#if activity.type === "commit"}

View File

@ -4,7 +4,7 @@ import { writable } from "svelte/store";
export type Activity = {
type: string;
timestamp: number;
timestampMs: number;
message: string;
};
@ -12,8 +12,8 @@ export type Session = {
id: string;
hash?: string;
meta: {
startTs: number;
lastTs: number;
startTimestampMs: number;
lastTimestampMs: number;
branch: string;
commit: string;
};

View File

@ -8,7 +8,7 @@
const sessionDisplayWidth = (session: Session) => {
let sessionDurationMinutes =
(session.meta.lastTs - session.meta.startTs) / 60;
(session.meta.lastTimestampMs - session.meta.startTimestampMs) / 60;
if (sessionDurationMinutes <= 10) {
return "w-40 min-w-40";
} else {

View File

@ -22,7 +22,7 @@
const sessionDisplayWidth = (session: Session) => {
let sessionDurationMinutes =
(session.meta.lastTs - session.meta.startTs) / 60;
(session.meta.lastTimestampMs - session.meta.startTimestampMs) / 60;
if (sessionDurationMinutes <= 10) {
return "w-40 min-w-40";
} else {
@ -39,8 +39,8 @@
const end = new Date(start.getTime() + 24 * 60 * 60 * 1000);
return sessions.filter((session) => {
return (
start <= new Date(session.meta.startTs * 1000) &&
new Date(session.meta.startTs * 1000) <= end
start <= new Date(session.meta.startTimestampMs * 1000) &&
new Date(session.meta.startTimestampMs * 1000) <= end
);
});
});

View File

@ -23,8 +23,8 @@
$: sessionsInWeek = derived([sessions], ([sessions]) => {
return sessions.filter((session) => {
return (
week.start <= new Date(session.meta.startTs * 1000) &&
new Date(session.meta.startTs * 1000) <= week.end
week.start <= new Date(session.meta.startTimestampMs * 1000) &&
new Date(session.meta.startTimestampMs * 1000) <= week.end
);
});
});
@ -256,8 +256,8 @@
>
{#each $sessionsInWeek as session}
<WeekBlockEntry
startTime={new Date(session.meta.startTs * 1000)}
endTime={new Date(session.meta.startTs * 1000)}
startTime={new Date(session.meta.startTimestampMs * 1000)}
endTime={new Date(session.meta.startTimestampMs * 1000)}
label={session.meta.branch}
href="/projects/{$project?.id}/sessions/{session.id}/"
/>