moved generated,spacetime into it's own package + many other things
This commit is contained in:
13
packages/spacetime/Cargo.toml
Normal file
13
packages/spacetime/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "mize-spacetime"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
spacetimedb = "2.1.0"
|
||||
log = "0.4"
|
||||
186
packages/spacetime/src/lib.rs
Normal file
186
packages/spacetime/src/lib.rs
Normal file
@@ -0,0 +1,186 @@
|
||||
use log::*;
|
||||
use spacetimedb::{reducer, table, Identity, ReducerContext, Table, Timestamp};
|
||||
|
||||
#[table(accessor = profiles, public)]
|
||||
pub struct Profile {
|
||||
#[primary_key]
|
||||
identity: Identity,
|
||||
#[unique]
|
||||
username: String,
|
||||
}
|
||||
|
||||
#[table(accessor = task_part, public)]
|
||||
pub struct TaskPart {
|
||||
#[primary_key]
|
||||
identity: Identity,
|
||||
start_of_current: Timestamp,
|
||||
current: Action,
|
||||
upcoming: Vec<Action>,
|
||||
}
|
||||
|
||||
#[table(accessor = activities, public)]
|
||||
pub struct Activity {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
id: u64,
|
||||
name: String,
|
||||
task: Option<u64>,
|
||||
parents_ids: Vec<u64>,
|
||||
}
|
||||
|
||||
#[table(accessor = tasks, public)]
|
||||
pub struct Task {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
id: u64,
|
||||
done: bool,
|
||||
name: String,
|
||||
parent: Option<u64>,
|
||||
}
|
||||
|
||||
#[table(accessor = action)]
|
||||
#[derive(Clone)]
|
||||
pub struct Action {
|
||||
name: String,
|
||||
activity: Option<u64>,
|
||||
task: Option<u64>,
|
||||
start: Option<Timestamp>,
|
||||
end: Option<Timestamp>,
|
||||
duration: Option<u64>,
|
||||
}
|
||||
|
||||
#[table(accessor = log_events, public)]
|
||||
pub struct LogEvent {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
id: u64,
|
||||
start: Timestamp,
|
||||
end: Timestamp,
|
||||
action: Action,
|
||||
}
|
||||
|
||||
#[reducer(init)]
|
||||
pub fn init(_ctx: &ReducerContext) {
|
||||
// Called when the module is initially published
|
||||
info!("hiiiiiii from ppc module");
|
||||
}
|
||||
|
||||
// the one from ppc, hardcoded rn, as we for now only support config at run time.
|
||||
// this needs to be loaded at build time. (this code runs as a wasm module on the spacetimedb server)
|
||||
const PPC_AUTH_CLIENT_ID: &str = "363331597203734531";
|
||||
|
||||
#[reducer(client_connected)]
|
||||
pub fn connect(ctx: &ReducerContext) -> Result<(), String> {
|
||||
check_auth(ctx)?;
|
||||
|
||||
// add user
|
||||
ctx.db.profiles().insert(Profile {
|
||||
identity: ctx.sender(),
|
||||
username: ctx.identity().to_string(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_auth(ctx: &ReducerContext) -> Result<(), String> {
|
||||
let jwt = ctx
|
||||
.sender_auth()
|
||||
.jwt()
|
||||
.ok_or("Authentication required".to_string())?;
|
||||
if jwt.issuer() != "https://auth.ppc.social" {
|
||||
return Err("Invalid issuer".to_string());
|
||||
}
|
||||
|
||||
if !jwt.audience().iter().any(|a| a == PPC_AUTH_CLIENT_ID) {
|
||||
return Err("Invalid audience".to_string());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[reducer(client_disconnected)]
|
||||
pub fn identity_disconnected(_ctx: &ReducerContext) {
|
||||
// Called everytime a client disconnects
|
||||
}
|
||||
|
||||
#[reducer]
|
||||
pub fn add_activity(ctx: &ReducerContext, name: String) {
|
||||
ctx.db.activities().insert(Activity {
|
||||
name,
|
||||
task: None,
|
||||
id: 0, // auto-increments
|
||||
parents_ids: Vec::new(),
|
||||
});
|
||||
}
|
||||
|
||||
#[reducer]
|
||||
pub fn set_activity_name(ctx: &ReducerContext, id: u64, name: String) {
|
||||
if let Some(old_ac) = ctx.db.activities().id().find(id) {
|
||||
ctx.db.activities().id().update(Activity { name, ..old_ac });
|
||||
} else {
|
||||
return ();
|
||||
}
|
||||
}
|
||||
|
||||
#[reducer]
|
||||
pub fn update_upcoming(ctx: &ReducerContext, upcoming: Vec<Action>) {
|
||||
if ctx.db.task_part().identity().find(ctx.sender()).is_none() {
|
||||
ctx.db.task_part().insert(TaskPart {
|
||||
upcoming,
|
||||
identity: ctx.sender(),
|
||||
current: Action {
|
||||
name: "filler".to_string(),
|
||||
activity: None,
|
||||
task: None,
|
||||
start: None,
|
||||
end: None,
|
||||
duration: None,
|
||||
},
|
||||
start_of_current: ctx.timestamp,
|
||||
});
|
||||
} else {
|
||||
ctx.db.task_part().identity().update(TaskPart {
|
||||
upcoming,
|
||||
..ctx.db.task_part().identity().find(&ctx.sender()).unwrap()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[reducer]
|
||||
pub fn next_action(ctx: &ReducerContext) -> Result<(), String> {
|
||||
if let Some(mut task_part) = ctx.db.task_part().identity().find(&ctx.sender()) {
|
||||
if task_part.upcoming.is_empty() {
|
||||
return Err("No upcoming actions".to_string());
|
||||
}
|
||||
let action = task_part.upcoming.remove(0);
|
||||
let start_of_old_action = task_part.start_of_current;
|
||||
ctx.db.task_part().identity().update(TaskPart {
|
||||
upcoming: task_part.upcoming,
|
||||
identity: task_part.identity,
|
||||
current: action.clone(),
|
||||
start_of_current: ctx.timestamp,
|
||||
});
|
||||
// create log event
|
||||
ctx.db.log_events().insert(LogEvent {
|
||||
start: start_of_old_action,
|
||||
end: ctx.timestamp,
|
||||
action: task_part.current,
|
||||
id: 0,
|
||||
});
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Task part data not found for this user".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[reducer]
|
||||
pub fn update_activity(ctx: &ReducerContext, activity: Activity) {
|
||||
if activity.id == 0 {
|
||||
ctx.db.activities().insert(activity);
|
||||
} else {
|
||||
ctx.db.activities().id().update(activity);
|
||||
}
|
||||
}
|
||||
|
||||
#[reducer]
|
||||
pub fn remove_activity(ctx: &ReducerContext, activity: Activity) {
|
||||
ctx.db.activities().delete(activity);
|
||||
}
|
||||
Reference in New Issue
Block a user