mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-28 12:05:22 +03:00
use ms timestamps everywhere
This commit is contained in:
parent
bd2c5b5809
commit
2e0f757cd9
@ -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"
|
||||
|
@ -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>>> {
|
||||
|
@ -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;
|
||||
|
@ -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)),
|
||||
}
|
||||
|
@ -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() },
|
||||
)
|
||||
];
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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")?;
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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"}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -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}/"
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user