Removed user groups
ci/woodpecker/push/ociImagePush Pipeline was successful Details

This commit is contained in:
Natty 2024-01-07 02:44:52 +01:00
parent 9f633d0749
commit c2cfd7e007
Signed by: natty
GPG Key ID: BF6CB659ADEE60EC
86 changed files with 716 additions and 1543 deletions

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::AntennaSrcEnum; use super::sea_orm_active_enums::AntennaSrcEnum;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
@ -27,8 +27,6 @@ pub struct Model {
pub case_sensitive: bool, pub case_sensitive: bool,
#[sea_orm(column_name = "withReplies")] #[sea_orm(column_name = "withReplies")]
pub with_replies: bool, pub with_replies: bool,
#[sea_orm(column_name = "userGroupJoiningId")]
pub user_group_joining_id: Option<String>,
pub users: Vec<String>, pub users: Vec<String>,
#[sea_orm(column_name = "excludeKeywords", column_type = "JsonBinary")] #[sea_orm(column_name = "excludeKeywords", column_type = "JsonBinary")]
pub exclude_keywords: Json, pub exclude_keywords: Json,
@ -48,14 +46,6 @@ pub enum Relation {
on_delete = "Cascade" on_delete = "Cascade"
)] )]
User, User,
#[sea_orm(
belongs_to = "super::user_group_joining::Entity",
from = "Column::UserGroupJoiningId",
to = "super::user_group_joining::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserGroupJoining,
#[sea_orm( #[sea_orm(
belongs_to = "super::user_list::Entity", belongs_to = "super::user_list::Entity",
from = "Column::UserListId", from = "Column::UserListId",
@ -78,12 +68,6 @@ impl Related<super::user::Entity> for Entity {
} }
} }
impl Related<super::user_group_joining::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupJoining.def()
}
}
impl Related<super::user_list::Entity> for Entity { impl Related<super::user_list::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::UserList.def() Relation::UserList.def()

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::MetaSensitivemediadetectionEnum; use super::sea_orm_active_enums::MetaSensitivemediadetectionEnum;
use super::sea_orm_active_enums::MetaSensitivemediadetectionsensitivityEnum; use super::sea_orm_active_enums::MetaSensitivemediadetectionsensitivityEnum;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
pub mod prelude; pub mod prelude;
@ -52,10 +52,6 @@ pub mod signin;
pub mod sw_subscription; pub mod sw_subscription;
pub mod used_username; pub mod used_username;
pub mod user; pub mod user;
pub mod user_group;
pub mod user_group_invitation;
pub mod user_group_invite;
pub mod user_group_joining;
pub mod user_ip; pub mod user_ip;
pub mod user_keypair; pub mod user_keypair;
pub mod user_list; pub mod user_list;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::MutedNoteReasonEnum; use super::sea_orm_active_enums::MutedNoteReasonEnum;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::NoteVisibilityEnum; use super::sea_orm_active_enums::NoteVisibilityEnum;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::NotificationTypeEnum; use super::sea_orm_active_enums::NotificationTypeEnum;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
@ -24,8 +24,6 @@ pub struct Model {
#[sea_orm(column_name = "followRequestId")] #[sea_orm(column_name = "followRequestId")]
pub follow_request_id: Option<String>, pub follow_request_id: Option<String>,
pub r#type: NotificationTypeEnum, pub r#type: NotificationTypeEnum,
#[sea_orm(column_name = "userGroupInvitationId")]
pub user_group_invitation_id: Option<String>,
#[sea_orm(column_name = "customBody")] #[sea_orm(column_name = "customBody")]
pub custom_body: Option<String>, pub custom_body: Option<String>,
#[sea_orm(column_name = "customHeader")] #[sea_orm(column_name = "customHeader")]
@ -78,14 +76,6 @@ pub enum Relation {
on_delete = "Cascade" on_delete = "Cascade"
)] )]
User1, User1,
#[sea_orm(
belongs_to = "super::user_group_invitation::Entity",
from = "Column::UserGroupInvitationId",
to = "super::user_group_invitation::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserGroupInvitation,
} }
impl Related<super::access_token::Entity> for Entity { impl Related<super::access_token::Entity> for Entity {
@ -106,10 +96,4 @@ impl Related<super::note::Entity> for Entity {
} }
} }
impl Related<super::user_group_invitation::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupInvitation.def()
}
}
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::PageVisibilityEnum; use super::sea_orm_active_enums::PageVisibilityEnum;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::PollNotevisibilityEnum; use super::sea_orm_active_enums::PollNotevisibilityEnum;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
pub use super::abuse_user_report::Entity as AbuseUserReport; pub use super::abuse_user_report::Entity as AbuseUserReport;
pub use super::access_token::Entity as AccessToken; pub use super::access_token::Entity as AccessToken;
@ -49,10 +49,6 @@ pub use super::signin::Entity as Signin;
pub use super::sw_subscription::Entity as SwSubscription; pub use super::sw_subscription::Entity as SwSubscription;
pub use super::used_username::Entity as UsedUsername; pub use super::used_username::Entity as UsedUsername;
pub use super::user::Entity as User; pub use super::user::Entity as User;
pub use super::user_group::Entity as UserGroup;
pub use super::user_group_invitation::Entity as UserGroupInvitation;
pub use super::user_group_invite::Entity as UserGroupInvite;
pub use super::user_group_joining::Entity as UserGroupJoining;
pub use super::user_ip::Entity as UserIp; pub use super::user_ip::Entity as UserIp;
pub use super::user_keypair::Entity as UserKeypair; pub use super::user_keypair::Entity as UserKeypair;
pub use super::user_list::Entity as UserList; pub use super::user_list::Entity as UserList;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::RelayStatusEnum; use super::sea_orm_active_enums::RelayStatusEnum;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -8,8 +8,6 @@ use serde::{Deserialize, Serialize};
pub enum AntennaSrcEnum { pub enum AntennaSrcEnum {
#[sea_orm(string_value = "all")] #[sea_orm(string_value = "all")]
All, All,
#[sea_orm(string_value = "group")]
Group,
#[sea_orm(string_value = "home")] #[sea_orm(string_value = "home")]
Home, Home,
#[sea_orm(string_value = "instances")] #[sea_orm(string_value = "instances")]

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -144,14 +144,6 @@ pub enum Relation {
Signin, Signin,
#[sea_orm(has_many = "super::sw_subscription::Entity")] #[sea_orm(has_many = "super::sw_subscription::Entity")]
SwSubscription, SwSubscription,
#[sea_orm(has_many = "super::user_group::Entity")]
UserGroup,
#[sea_orm(has_many = "super::user_group_invitation::Entity")]
UserGroupInvitation,
#[sea_orm(has_many = "super::user_group_invite::Entity")]
UserGroupInvite,
#[sea_orm(has_many = "super::user_group_joining::Entity")]
UserGroupJoining,
#[sea_orm(has_one = "super::user_keypair::Entity")] #[sea_orm(has_one = "super::user_keypair::Entity")]
UserKeypair, UserKeypair,
#[sea_orm(has_many = "super::user_list::Entity")] #[sea_orm(has_many = "super::user_list::Entity")]
@ -332,30 +324,6 @@ impl Related<super::sw_subscription::Entity> for Entity {
} }
} }
impl Related<super::user_group::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroup.def()
}
}
impl Related<super::user_group_invitation::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupInvitation.def()
}
}
impl Related<super::user_group_invite::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupInvite.def()
}
}
impl Related<super::user_group_joining::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupJoining.def()
}
}
impl Related<super::user_keypair::Entity> for Entity { impl Related<super::user_keypair::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::UserKeypair.def() Relation::UserKeypair.def()

View File

@ -1,62 +0,0 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "user_group")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
pub name: String,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "isPrivate")]
pub is_private: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
#[sea_orm(has_many = "super::user_group_invitation::Entity")]
UserGroupInvitation,
#[sea_orm(has_many = "super::user_group_invite::Entity")]
UserGroupInvite,
#[sea_orm(has_many = "super::user_group_joining::Entity")]
UserGroupJoining,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::user_group_invitation::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupInvitation.def()
}
}
impl Related<super::user_group_invite::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupInvite.def()
}
}
impl Related<super::user_group_joining::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroupJoining.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,59 +0,0 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "user_group_invitation")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "userGroupId")]
pub user_group_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::notification::Entity")]
Notification,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
#[sea_orm(
belongs_to = "super::user_group::Entity",
from = "Column::UserGroupId",
to = "super::user_group::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserGroup,
}
impl Related<super::notification::Entity> for Entity {
fn to() -> RelationDef {
Relation::Notification.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::user_group::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroup.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,51 +0,0 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "user_group_invite")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "userGroupId")]
pub user_group_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
#[sea_orm(
belongs_to = "super::user_group::Entity",
from = "Column::UserGroupId",
to = "super::user_group::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserGroup,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::user_group::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroup.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,59 +0,0 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "user_group_joining")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: String,
#[sea_orm(column_name = "createdAt")]
pub created_at: DateTimeWithTimeZone,
#[sea_orm(column_name = "userId")]
pub user_id: String,
#[sea_orm(column_name = "userGroupId")]
pub user_group_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_many = "super::antenna::Entity")]
Antenna,
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
User,
#[sea_orm(
belongs_to = "super::user_group::Entity",
from = "Column::UserGroupId",
to = "super::user_group::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
UserGroup,
}
impl Related<super::antenna::Entity> for Entity {
fn to() -> RelationDef {
Relation::Antenna.def()
}
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::user_group::Entity> for Entity {
fn to() -> RelationDef {
Relation::UserGroup.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use super::sea_orm_active_enums::UserProfileFfvisibilityEnum; use super::sea_orm_active_enums::UserProfileFfvisibilityEnum;
use super::sea_orm_active_enums::UserProfileMutingnotificationtypesEnum; use super::sea_orm_active_enums::UserProfileMutingnotificationtypesEnum;

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -1,4 +1,4 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.10
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -4,6 +4,7 @@ mod m20220101_000001_bootstrap;
mod m20230729_201733_drop_messaging_integrations; mod m20230729_201733_drop_messaging_integrations;
mod m20230729_212237_user_unique_idx; mod m20230729_212237_user_unique_idx;
mod m20230806_142918_drop_featured_note_option; mod m20230806_142918_drop_featured_note_option;
mod m20240107_005747_remove_user_groups;
pub struct Migrator; pub struct Migrator;
@ -15,6 +16,7 @@ impl MigratorTrait for Migrator {
Box::new(m20230729_201733_drop_messaging_integrations::Migration), Box::new(m20230729_201733_drop_messaging_integrations::Migration),
Box::new(m20230729_212237_user_unique_idx::Migration), Box::new(m20230729_212237_user_unique_idx::Migration),
Box::new(m20230806_142918_drop_featured_note_option::Migration), Box::new(m20230806_142918_drop_featured_note_option::Migration),
Box::new(m20240107_005747_remove_user_groups::Migration),
] ]
} }
} }

View File

@ -0,0 +1,181 @@
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let db = manager.get_connection();
db.execute_unprepared(
r#"
DELETE FROM "antenna" WHERE "src" = 'group';
ALTER TYPE "antenna_src_enum" RENAME TO "antenna_src_enum_old";
CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list', 'instances');
ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::text::antenna_src_enum;
DROP TYPE "antenna_src_enum_old";
ALTER TABLE "antenna" DROP COLUMN "userGroupJoiningId";
ALTER TABLE "notification" DROP COLUMN "userGroupInvitationId";
ALTER TABLE "user_profile" ALTER COLUMN "emailNotificationTypes"
SET DEFAULT '["follow", "receiveFollowRequest"]'::jsonb;
DROP TABLE "user_group_invitation";
DROP TABLE "user_group_joining";
DROP TABLE "user_group_invite";
DROP TABLE "user_group";
"#,
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let db = manager.get_connection();
db.execute_unprepared(
r#"
create table user_group
(
id varchar(32) not null
constraint "PK_3c29fba6fe013ec8724378ce7c9"
primary key,
"createdAt" timestamp with time zone not null,
name varchar(256) not null,
"userId" varchar(32) not null
constraint "FK_3d6b372788ab01be58853003c93"
references "user"
on delete cascade,
"isPrivate" boolean default false not null
);
comment on column user_group."createdAt" is 'The created date of the UserGroup.';
comment on column user_group."userId" is 'The ID of owner.';
create index "IDX_20e30aa35180e317e133d75316"
on user_group ("createdAt");
create index "IDX_3d6b372788ab01be58853003c9"
on user_group ("userId");
create table user_group_invitation
(
id varchar(32) not null
constraint "PK_160c63ec02bf23f6a5c5e8140d6"
primary key,
"createdAt" timestamp with time zone not null,
"userId" varchar(32) not null
constraint "FK_bfbc6305547539369fe73eb144a"
references "user"
on delete cascade,
"userGroupId" varchar(32) not null
constraint "FK_5cc8c468090e129857e9fecce5a"
references user_group
on delete cascade
);
comment on column user_group_invitation."createdAt" is 'The created date of the UserGroupInvitation.';
comment on column user_group_invitation."userId" is 'The user ID.';
comment on column user_group_invitation."userGroupId" is 'The group ID.';
create index "IDX_bfbc6305547539369fe73eb144"
on user_group_invitation ("userId");
create index "IDX_5cc8c468090e129857e9fecce5"
on user_group_invitation ("userGroupId");
create unique index "IDX_e9793f65f504e5a31fbaedbf2f"
on user_group_invitation ("userId", "userGroupId");
create table user_group_joining
(
id varchar(32) not null
constraint "PK_15f2425885253c5507e1599cfe7"
primary key,
"createdAt" timestamp with time zone not null,
"userId" varchar(32) not null
constraint "FK_f3a1b4bd0c7cabba958a0c0b231"
references "user"
on delete cascade,
"userGroupId" varchar(32) not null
constraint "FK_67dc758bc0566985d1b3d399865"
references user_group
on delete cascade
);
comment on column user_group_joining."createdAt" is 'The created date of the UserGroupJoining.';
comment on column user_group_joining."userId" is 'The user ID.';
comment on column user_group_joining."userGroupId" is 'The group ID.';
create index "IDX_f3a1b4bd0c7cabba958a0c0b23"
on user_group_joining ("userId");
create index "IDX_67dc758bc0566985d1b3d39986"
on user_group_joining ("userGroupId");
create unique index "IDX_d9ecaed8c6dc43f3592c229282"
on user_group_joining ("userId", "userGroupId");
create table user_group_invite
(
id varchar(32) not null
constraint "PK_3893884af0d3a5f4d01e7921a97"
primary key,
"createdAt" timestamp with time zone not null,
"userId" varchar(32) not null
constraint "FK_1039988afa3bf991185b277fe03"
references "user"
on delete cascade,
"userGroupId" varchar(32) not null
constraint "FK_e10924607d058004304611a436a"
references user_group
on delete cascade
);
alter table user_group_invite
owner to "example-calckey-user";
create index "IDX_1039988afa3bf991185b277fe0"
on user_group_invite ("userId");
create index "IDX_e10924607d058004304611a436"
on user_group_invite ("userGroupId");
create unique index "IDX_78787741f9010886796f2320a4"
on user_group_invite ("userId", "userGroupId");
ALTER TABLE "user_profile" ALTER COLUMN "emailNotificationTypes"
SET DEFAULT '["follow", "receiveFollowRequest", "groupInvited"]'::jsonb;
alter table antenna add "userGroupJoiningId" varchar(32)
constraint "FK_ccbf5a8c0be4511133dcc50ddeb"
references user_group_joining
on delete cascade;
alter table notification add column "userGroupInvitationId" varchar(32)
constraint "FK_8fe87814e978053a53b1beb7e98"
references user_group_invitation
on delete cascade;
ALTER TYPE "antenna_src_enum" RENAME TO "antenna_src_enum_old";
CREATE TYPE "antenna_src_enum" AS ENUM('home', 'all', 'users', 'list', 'group', 'instances');
ALTER TABLE "antenna" ALTER COLUMN "src" TYPE "antenna_src_enum" USING "src"::text::antenna_src_enum;
DROP TYPE "antenna_src_enum_old";
"#,
)
.await?;
Ok(())
}
}

View File

@ -1,29 +0,0 @@
# 0.0.14
- remove needless Object.freeze()
# 0.0.13
- expose ChannelConnection and Channels types
# 0.0.12
- fix a bug that cannot connect to streaming
# 0.0.11
- update user type
- add missing main stream types
# 0.0.10
- add consts
# 0.0.9
- add list of api permission
- Update Note type
# 0.0.8
- add type definition for `messagingMessage` event to main stream channel
- Update Note type
# 0.0.7
- Notificationsの型を修正
- MessagingMessageの型を修正
- UserLiteの型を修正
- apiでネイティブfetchを格納する際に無名関数でラップするように

View File

@ -18,7 +18,6 @@ import {
Instance, Instance,
LiteInstanceMetadata, LiteInstanceMetadata,
MeDetailed, MeDetailed,
MessagingMessage,
Note, Note,
NoteFavorite, NoteFavorite,
NoteReaction, NoteReaction,
@ -30,7 +29,6 @@ import {
Stats, Stats,
User, User,
UserDetailed, UserDetailed,
UserGroup,
UserList, UserList,
UserSorting, UserSorting,
} from "./entities"; } from "./entities";
@ -703,7 +701,6 @@ export type Endpoints = {
}; };
res: MeDetailed; res: MeDetailed;
}; };
"i/user-group-invites": { req: TODO; res: TODO };
"i/2fa/done": { req: TODO; res: TODO }; "i/2fa/done": { req: TODO; res: TODO };
"i/2fa/key-done": { req: TODO; res: TODO }; "i/2fa/key-done": { req: TODO; res: TODO };
"i/2fa/password-less": { req: TODO; res: TODO }; "i/2fa/password-less": { req: TODO; res: TODO };
@ -713,40 +710,6 @@ export type Endpoints = {
"i/2fa/remove-key": { req: TODO; res: TODO }; "i/2fa/remove-key": { req: TODO; res: TODO };
"i/2fa/unregister": { req: TODO; res: TODO }; "i/2fa/unregister": { req: TODO; res: TODO };
// messaging
"messaging/history": {
req: { limit?: number; group?: boolean };
res: MessagingMessage[];
};
"messaging/messages": {
req: {
userId?: User["id"];
groupId?: UserGroup["id"];
limit?: number;
sinceId?: MessagingMessage["id"];
untilId?: MessagingMessage["id"];
markAsRead?: boolean;
};
res: MessagingMessage[];
};
"messaging/messages/create": {
req: {
userId?: User["id"];
groupId?: UserGroup["id"];
text?: string;
fileId?: DriveFile["id"];
};
res: MessagingMessage;
};
"messaging/messages/delete": {
req: { messageId: MessagingMessage["id"] };
res: null;
};
"messaging/messages/read": {
req: { messageId: MessagingMessage["id"] };
res: null;
};
// meta // meta
meta: { meta: {
req: { detail?: boolean }; req: { detail?: boolean };
@ -1010,17 +973,6 @@ export type Endpoints = {
}; };
"users/gallery/posts": { req: TODO; res: TODO }; "users/gallery/posts": { req: TODO; res: TODO };
"users/get-frequently-replied-users": { req: TODO; res: TODO }; "users/get-frequently-replied-users": { req: TODO; res: TODO };
"users/groups/create": { req: TODO; res: TODO };
"users/groups/delete": { req: { groupId: UserGroup["id"] }; res: null };
"users/groups/invitations/accept": { req: TODO; res: TODO };
"users/groups/invitations/reject": { req: TODO; res: TODO };
"users/groups/invite": { req: TODO; res: TODO };
"users/groups/joined": { req: TODO; res: TODO };
"users/groups/owned": { req: TODO; res: TODO };
"users/groups/pull": { req: TODO; res: TODO };
"users/groups/show": { req: TODO; res: TODO };
"users/groups/transfer": { req: TODO; res: TODO };
"users/groups/update": { req: TODO; res: TODO };
"users/lists/create": { req: { name: string }; res: UserList }; "users/lists/create": { req: { name: string }; res: UserList };
"users/lists/delete": { req: { listId: UserList["id"] }; res: null }; "users/lists/delete": { req: { listId: UserList["id"] }; res: null };
"users/lists/list": { req: NoParams; res: UserList[] }; "users/lists/list": { req: NoParams; res: UserList[] };

View File

@ -9,7 +9,6 @@ export const notificationTypes = [
"pollEnded", "pollEnded",
"receiveFollowRequest", "receiveFollowRequest",
"followRequestAccepted", "followRequestAccepted",
"groupInvited",
"app", "app",
] as const; ] as const;
@ -49,8 +48,6 @@ export const permissions = [
"write:pages", "write:pages",
"write:page-likes", "write:page-likes",
"read:page-likes", "read:page-likes",
"read:user-groups",
"write:user-groups",
"read:gallery", "read:gallery",
"write:gallery", "write:gallery",
"read:gallery-likes", "read:gallery-likes",

View File

@ -74,8 +74,6 @@ export type UserDetailed = UserLite & {
url: string | null; url: string | null;
}; };
export type UserGroup = TODO;
export type UserList = { export type UserList = {
id: ID; id: ID;
createdAt: DateString; createdAt: DateString;
@ -94,7 +92,6 @@ export type MeDetailed = UserDetailed & {
hasUnreadAnnouncement: boolean; hasUnreadAnnouncement: boolean;
hasUnreadAntenna: boolean; hasUnreadAntenna: boolean;
hasUnreadMentions: boolean; hasUnreadMentions: boolean;
hasUnreadMessagingMessage: boolean;
hasUnreadNotification: boolean; hasUnreadNotification: boolean;
hasUnreadSpecifiedNotes: boolean; hasUnreadSpecifiedNotes: boolean;
hideOnlineStatus: boolean; hideOnlineStatus: boolean;
@ -232,12 +229,6 @@ export type Notification = {
user: User; user: User;
userId: User["id"]; userId: User["id"];
} }
| {
type: "groupInvited";
invitation: UserGroup;
user: User;
userId: User["id"];
}
| { | {
type: "app"; type: "app";
header?: string | null; header?: string | null;
@ -246,22 +237,6 @@ export type Notification = {
} }
); );
export type MessagingMessage = {
id: ID;
createdAt: DateString;
file: DriveFile | null;
fileId: DriveFile["id"] | null;
isRead: boolean;
reads: User["id"][];
text: string | null;
user: User;
userId: User["id"];
recipient?: User | null;
recipientId: User["id"] | null;
group?: UserGroup | null;
groupId: UserGroup["id"] | null;
};
export type CustomEmoji = { export type CustomEmoji = {
id: string; id: string;
name: string; name: string;
@ -379,9 +354,8 @@ export type Antenna = {
name: string; name: string;
keywords: string[][]; // TODO keywords: string[][]; // TODO
excludeKeywords: string[][]; // TODO excludeKeywords: string[][]; // TODO
src: "home" | "all" | "users" | "list" | "group" | "instances"; src: "home" | "all" | "users" | "list" | "instances";
userListId: ID | null; // TODO userListId: ID | null; // TODO
userGroupId: ID | null; // TODO
users: string[]; // TODO users: string[]; // TODO
instances: string[]; instances: string[];
caseSensitive: boolean; caseSensitive: boolean;

View File

@ -3,12 +3,10 @@ import type {
CustomEmoji, CustomEmoji,
DriveFile, DriveFile,
MeDetailed, MeDetailed,
MessagingMessage,
Note, Note,
Notification, Notification,
PageEvent, PageEvent,
User, User,
UserGroup,
} from "./entities"; } from "./entities";
type FIXME = any; type FIXME = any;
@ -33,9 +31,6 @@ export type Channels = {
readAllUnreadMentions: () => void; readAllUnreadMentions: () => void;
unreadSpecifiedNote: (payload: Note["id"]) => void; unreadSpecifiedNote: (payload: Note["id"]) => void;
readAllUnreadSpecifiedNotes: () => void; readAllUnreadSpecifiedNotes: () => void;
readAllMessagingMessages: () => void;
messagingMessage: (payload: MessagingMessage) => void;
unreadMessagingMessage: (payload: MessagingMessage) => void;
readAllAntennas: () => void; readAllAntennas: () => void;
unreadAntenna: (payload: Antenna) => void; unreadAntenna: (payload: Antenna) => void;
readAllAnnouncements: () => void; readAllAnnouncements: () => void;
@ -97,23 +92,6 @@ export type Channels = {
}; };
receives: null; receives: null;
}; };
messaging: {
params: {
otherparty?: User["id"] | null;
group?: UserGroup["id"] | null;
};
events: {
message: (payload: MessagingMessage) => void;
deleted: (payload: MessagingMessage["id"]) => void;
read: (payload: MessagingMessage["id"][]) => void;
typers: (payload: User[]) => void;
};
receives: {
read: {
id: MessagingMessage["id"];
};
};
};
serverStats: { serverStats: {
params: null; params: null;
events: { events: {
@ -189,7 +167,5 @@ export type NoteUpdatedEvent =
export type BroadcastEvents = { export type BroadcastEvents = {
noteUpdated: (payload: NoteUpdatedEvent) => void; noteUpdated: (payload: NoteUpdatedEvent) => void;
emojiAdded: (payload: { emojiAdded: (payload: { emoji: CustomEmoji }) => void;
emoji: CustomEmoji;
}) => void;
}; };

View File

@ -35,10 +35,6 @@
v-else-if="notification.type === 'followRequestAccepted'" v-else-if="notification.type === 'followRequestAccepted'"
class="ph-check ph-bold" class="ph-check ph-bold"
></i> ></i>
<i
v-else-if="notification.type === 'groupInvited'"
class="ph-identification-card ph-bold"
></i>
<i <i
v-else-if="notification.type === 'renote'" v-else-if="notification.type === 'renote'"
class="ph-repeat ph-bold" class="ph-repeat ph-bold"
@ -237,28 +233,6 @@
/> />
</div> </div>
</span> </span>
<span
v-if="notification.type === 'groupInvited'"
class="text"
style="opacity: 0.7"
>{{ i18n.ts.groupInvited }}:
<b>{{ notification.invitation.group.name }}</b>
<div v-if="full && !groupInviteDone">
<button
class="_textButton"
@click="acceptGroupInvitation()"
>
{{ i18n.ts.accept }}
</button>
|
<button
class="_textButton"
@click="rejectGroupInvitation()"
>
{{ i18n.ts.reject }}
</button>
</div>
</span>
<span v-if="notification.type === 'app'" class="text"> <span v-if="notification.type === 'app'" class="text">
<Mfm :text="notification.body" :nowrap="!full" /> <Mfm :text="notification.body" :nowrap="!full" />
</span> </span>
@ -358,21 +332,6 @@ onUnmounted(() => {
}); });
const followRequestDone = ref(false); const followRequestDone = ref(false);
const groupInviteDone = ref(false);
const acceptGroupInvitation = () => {
groupInviteDone.value = true;
os.apiWithDialog("users/groups/invitations/accept", {
invitationId: props.notification.invitation.id,
});
};
const rejectGroupInvitation = () => {
groupInviteDone.value = true;
os.api("users/groups/invitations/reject", {
invitationId: props.notification.invitation.id,
});
};
useTooltip(reactionRef, (showing) => { useTooltip(reactionRef, (showing) => {
if (props.notification.type !== "reaction") return; if (props.notification.type !== "reaction") return;

View File

@ -51,14 +51,6 @@ export const navbarItemDef = reactive({
show: computed(() => $i != null), show: computed(() => $i != null),
to: "/my/lists", to: "/my/lists",
}, },
/*
groups: {
title: 'groups',
icon: 'ph-users-three ph-bold ph-lg',
show: computed(() => $i != null),
to: '/my/groups',
},
*/
antennas: { antennas: {
title: "antennas", title: "antennas",
icon: "ph-flying-saucer ph-bold ph-lg", icon: "ph-flying-saucer ph-bold ph-lg",
@ -87,11 +79,6 @@ export const navbarItemDef = reactive({
show: computed(() => $i != null), show: computed(() => $i != null),
to: "/my/clips", to: "/my/clips",
}, },
groups: {
title: "groups",
icon: "ph-users-three ph-bold ph-lg",
to: "/my/groups",
},
ui: { ui: {
title: "switchUi", title: "switchUi",
icon: "ph-layout ph-bold ph-lg", icon: "ph-layout ph-bold ph-lg",

View File

@ -18,7 +18,6 @@ let draft = $ref({
name: "", name: "",
src: "all", src: "all",
userListId: null, userListId: null,
userGroupId: null,
users: [], users: [],
instances: [], instances: [],
keywords: [], keywords: [],

View File

@ -12,7 +12,6 @@
{{ i18n.ts._antennaSources.users }} {{ i18n.ts._antennaSources.users }}
</option> </option>
<!--<option value="list">{{ i18n.ts._antennaSources.userList }}</option>--> <!--<option value="list">{{ i18n.ts._antennaSources.userList }}</option>-->
<!--<option value="group">{{ i18n.ts._antennaSources.userGroup }}</option>-->
<option value="instances"> <option value="instances">
{{ i18n.ts._antennaSources.instances }} {{ i18n.ts._antennaSources.instances }}
</option> </option>
@ -31,20 +30,6 @@
{{ list.name }} {{ list.name }}
</option> </option>
</MkSelect> </MkSelect>
<MkSelect
v-else-if="src === 'group'"
v-model="userGroupId"
class="_formBlock"
>
<template #label>{{ i18n.ts.userGroup }}</template>
<option
v-for="group in userGroups"
:key="group.id"
:value="group.id"
>
{{ group.name }}
</option>
</MkSelect>
<MkTextarea <MkTextarea
v-else-if="src === 'users'" v-else-if="src === 'users'"
v-model="users" v-model="users"
@ -137,7 +122,6 @@ const emit = defineEmits<{
let name: string = $ref(props.antenna.name); let name: string = $ref(props.antenna.name);
let src: string = $ref(props.antenna.src); let src: string = $ref(props.antenna.src);
let userListId: any = $ref(props.antenna.userListId); let userListId: any = $ref(props.antenna.userListId);
let userGroupId: any = $ref(props.antenna.userGroupId);
let users: string = $ref(props.antenna.users.join("\n")); let users: string = $ref(props.antenna.users.join("\n"));
let instances: string = $ref(props.antenna.instances.join("\n")); let instances: string = $ref(props.antenna.instances.join("\n"));
let keywords: string = $ref( let keywords: string = $ref(
@ -151,7 +135,6 @@ let withReplies: boolean = $ref(props.antenna.withReplies);
let withFile: boolean = $ref(props.antenna.withFile); let withFile: boolean = $ref(props.antenna.withFile);
let notify: boolean = $ref(props.antenna.notify); let notify: boolean = $ref(props.antenna.notify);
let userLists: any = $ref(null); let userLists: any = $ref(null);
let userGroups: any = $ref(null);
watch( watch(
() => src, () => src,
@ -159,13 +142,6 @@ watch(
if (src === "list" && userLists === null) { if (src === "list" && userLists === null) {
userLists = await os.api("users/lists/list"); userLists = await os.api("users/lists/list");
} }
if (src === "group" && userGroups === null) {
const groups1 = await os.api("users/groups/owned");
const groups2 = await os.api("users/groups/joined");
userGroups = [...groups1, ...groups2];
}
} }
); );
@ -174,7 +150,6 @@ async function saveAntenna() {
name, name,
src, src,
userListId, userListId,
userGroupId,
withReplies, withReplies,
withFile, withFile,
notify, notify,

View File

@ -1,201 +0,0 @@
<template>
<MkStickyContainer>
<template #header><MkPageHeader :actions="headerActions" /></template>
<div class="mk-group-page">
<div class="_section members _gap">
<div class="_content">
<div class="users">
<div
v-for="user in users"
:key="user.id"
class="user _panel"
>
<MagAvatarResolvingProxy
:user="user"
class="avatar"
:show-indicator="true"
/>
<div class="body">
<MkUserName :user="user" class="name" />
<MkAcct :user="user" class="acct" />
</div>
<div class="action">
<button
class="_button"
@click="removeUser(user)"
>
<i class="ph-x ph-bold ph-lg"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</MkStickyContainer>
</template>
<script lang="ts" setup>
import { computed, ref, watch } from "vue";
import { definePageMetadata } from "@/scripts/page-metadata";
import { i18n } from "@/i18n";
import { useRouter } from "@/router";
import * as os from "@/os";
const props = defineProps<{
groupId: {
type: string;
required: true;
};
}>();
const users = ref<any[]>([]);
const group = ref<any>();
const router = useRouter();
watch(
() => props.groupId,
() => {
fetch();
}
);
async function fetch() {
os.api("users/groups/show", {
groupId: props.groupId,
}).then((gp) => {
group.value = gp;
os.api("users/show", {
userIds: group.value.userIds,
}).then((us) => {
users.value = us;
});
});
}
fetch();
function invite() {
os.selectUser().then((user) => {
os.apiWithDialog("users/groups/invite", {
groupId: group.value.id,
userId: user.id,
});
});
}
function removeUser(user) {
os.api("users/groups/pull", {
groupId: group.value.id,
userId: user.id,
}).then(() => {
users.value = users.value.filter((x) => x.id !== user.id);
});
}
async function renameGroup() {
const { canceled, result: name } = await os.inputText({
title: i18n.ts.groupName,
default: group.value.name,
});
if (canceled) return;
await os.api("users/groups/update", {
groupId: group.value.id,
name: name,
});
group.value.name = name;
}
function transfer() {
os.selectUser().then((user) => {
os.apiWithDialog("users/groups/transfer", {
groupId: group.value.id,
userId: user.id,
});
});
}
async function deleteGroup() {
const { canceled } = await os.confirm({
type: "warning",
text: i18n.t("removeAreYouSure", { x: group.value.name }),
});
if (canceled) return;
await os.apiWithDialog("users/groups/delete", {
groupId: group.value.id,
});
router.push("/my/groups");
}
definePageMetadata(
computed(() => ({
title: i18n.ts.members,
icon: "ph-users-three ph-bold ph-lg",
}))
);
const headerActions = $computed(() => [
{
icon: "ph-plus ph-bold ph-lg",
text: i18n.ts.invite,
handler: invite,
},
{
icon: "ph-cursor-text ph-bold ph-lg",
text: i18n.ts.rename,
handler: renameGroup,
},
{
icon: "ph-arrows-left-right ph-bold ph-lg",
text: i18n.ts.transfer,
handler: transfer,
},
{
icon: "ph-trash ph-bold ph-lg",
text: i18n.ts.delete,
handler: deleteGroup,
},
]);
</script>
<style lang="scss" scoped>
.mk-group-page {
> .members {
> ._content {
> .users {
> ._panel {
margin: 1rem 2rem;
}
> .user {
display: flex;
align-items: center;
padding: 16px;
> .avatar {
width: 50px;
height: 50px;
}
> .body {
flex: 1;
padding: 8px;
> .name {
display: block;
font-weight: bold;
}
> .acct {
opacity: 0.5;
}
}
}
}
}
}
}
</style>

View File

@ -1,136 +0,0 @@
<template>
<MkStickyContainer>
<template #header
><MkPageHeader :actions="headerActions" :display-back-button="true"
/></template>
<MkSpacer :content-max="800" :margin-min="20">
<MkButton
primary
style="margin: 0 auto var(--margin) auto"
@click="create"
><i class="ph-plus ph-bold ph-lg"></i>
{{ i18n.ts.createGroup }}</MkButton
>
<MkPagination
v-slot="{ items }"
ref="owned"
:pagination="ownedPagination"
>
<div v-for="group in items" :key="group.id" class="_card">
<div class="_title">
<MkA :to="`/my/groups/${group.id}`" class="_link">{{
group.name
}}</MkA>
</div>
<div class="_content">
<MagAvatars :user-ids="group.userIds" />
</div>
</div>
</MkPagination>
<MkPagination
v-slot="{ items }"
ref="joined"
:pagination="joinedPagination"
>
<div v-for="group in items" :key="group.id" class="_card">
<div class="_title">{{ group.name }}</div>
<div class="_content">
<MagAvatars :user-ids="group.userIds" />
</div>
<div class="_footer">
<MkButton danger @click="leave(group)">{{
i18n.ts.leaveGroup
}}</MkButton>
</div>
</div>
</MkPagination>
</MkSpacer>
</MkStickyContainer>
</template>
<script lang="ts" setup>
import { computed, ref } from "vue";
import MkPagination from "@/components/MkPagination.vue";
import MkButton from "@/components/MkButton.vue";
import MagAvatars from "@/components/MagAvatars.vue";
import * as os from "@/os";
import { definePageMetadata } from "@/scripts/page-metadata";
import { i18n } from "@/i18n";
import MkStickyContainer from "@/components/global/MkStickyContainer.vue";
const owned = ref("owned");
const joined = ref("joined");
const ownedPagination = {
endpoint: "users/groups/owned" as const,
limit: 10,
};
const joinedPagination = {
endpoint: "users/groups/joined" as const,
limit: 10,
};
const headerActions = $computed(() => [
{
icon: "ph-plus ph-bold ph-lg",
text: i18n.ts.createGroup,
handler: create,
},
]);
definePageMetadata(
computed(() => ({
title: i18n.ts.groups,
icon: "ph-users-three ph-bold ph-lg",
}))
);
async function create() {
const { canceled, result: name } = await os.inputText({
title: i18n.ts.groupName,
});
if (canceled) return;
await os.api("users/groups/create", { name: name });
owned.value.reload();
os.success();
}
async function leave(group) {
const { canceled } = await os.confirm({
type: "warning",
text: i18n.t("leaveGroupConfirm", { name: group.name }),
});
if (canceled) return;
os.apiWithDialog("users/groups/leave", {
groupId: group.id,
}).then(() => {
joined.value.reload();
});
}
</script>
<style lang="scss" scoped>
._fullinfo {
display: none !important;
}
._card {
margin-bottom: 1rem;
._title {
font-size: 1.2rem;
font-weight: bold;
}
._content {
padding: 20px;
> .defgtij {
padding: 0;
}
}
._footer {
display: flex;
justify-content: flex-end;
}
}
</style>

View File

@ -50,12 +50,6 @@
> >
{{ i18n.ts._notification._types.receiveFollowRequest }} {{ i18n.ts._notification._types.receiveFollowRequest }}
</FormSwitch> </FormSwitch>
<FormSwitch
v-model="emailNotification_groupInvited"
class="_formBlock"
>
{{ i18n.ts._notification._types.groupInvited }}
</FormSwitch>
</FormSection> </FormSection>
</div> </div>
</template> </template>
@ -106,9 +100,6 @@ const emailNotification_follow = ref(
const emailNotification_receiveFollowRequest = ref( const emailNotification_receiveFollowRequest = ref(
$i!.emailNotificationTypes.includes("receiveFollowRequest") $i!.emailNotificationTypes.includes("receiveFollowRequest")
); );
const emailNotification_groupInvited = ref(
$i!.emailNotificationTypes.includes("groupInvited")
);
const saveNotificationSettings = () => { const saveNotificationSettings = () => {
os.api("i/update", { os.api("i/update", {
@ -122,7 +113,6 @@ const saveNotificationSettings = () => {
? "receiveFollowRequest" ? "receiveFollowRequest"
: null, : null,
], ],
...[emailNotification_groupInvited.value ? "groupInvited" : null],
].filter((x) => x != null), ].filter((x) => x != null),
}); });
}; };
@ -134,7 +124,6 @@ watch(
emailNotification_quote, emailNotification_quote,
emailNotification_follow, emailNotification_follow,
emailNotification_receiveFollowRequest, emailNotification_receiveFollowRequest,
emailNotification_groupInvited,
], ],
() => { () => {
saveNotificationSettings(); saveNotificationSettings();

View File

@ -13,9 +13,6 @@
<FormButton class="_formBlock" @click="readAllUnreadNotes">{{ <FormButton class="_formBlock" @click="readAllUnreadNotes">{{
i18n.ts.markAsReadAllUnreadNotes i18n.ts.markAsReadAllUnreadNotes
}}</FormButton> }}</FormButton>
<FormButton class="_formBlock" @click="readAllMessagingMessages">{{
i18n.ts.markAsReadAllTalkMessages
}}</FormButton>
</FormSection> </FormSection>
<FormSection> <FormSection>
<template #label>{{ i18n.ts.pushNotification }}</template> <template #label>{{ i18n.ts.pushNotification }}</template>
@ -52,7 +49,6 @@
import { defineAsyncComponent } from "vue"; import { defineAsyncComponent } from "vue";
import { notificationTypes } from "calckey-js"; import { notificationTypes } from "calckey-js";
import FormButton from "@/components/MkButton.vue"; import FormButton from "@/components/MkButton.vue";
import FormLink from "@/components/form/link.vue";
import FormSection from "@/components/form/section.vue"; import FormSection from "@/components/form/section.vue";
import * as os from "@/os"; import * as os from "@/os";
import { $i } from "@/account"; import { $i } from "@/account";
@ -73,10 +69,6 @@ async function readAllUnreadNotes() {
await os.api("i/read-all-unread-notes"); await os.api("i/read-all-unread-notes");
} }
async function readAllMessagingMessages() {
await os.api("i/read-all-messaging-messages");
}
async function readAllNotifications() { async function readAllNotifications() {
await os.api("notifications/mark-all-as-read"); await os.api("notifications/mark-all-as-read");
} }

View File

@ -607,16 +607,6 @@ export const routes = [
component: page(() => import("./pages/my-clips/index.vue")), component: page(() => import("./pages/my-clips/index.vue")),
loginRequired: true, loginRequired: true,
}, },
{
path: "/my/groups",
component: page(() => import("./pages/my-groups/index.vue")),
loginRequired: true,
},
{
path: "/my/groups/:groupId",
component: page(() => import("./pages/my-groups/group.vue")),
loginRequired: true,
},
{ {
path: "/my/antennas/create", path: "/my/antennas/create",
component: page(() => import("./pages/my-antennas/create.vue")), component: page(() => import("./pages/my-antennas/create.vue")),

View File

@ -41,29 +41,6 @@ export function getUserMenu(
}); });
} }
async function inviteGroup() {
const groups = await os.api("users/groups/owned");
if (groups.length === 0) {
os.alert({
type: "error",
text: i18n.ts.youHaveNoGroups,
});
return;
}
const { canceled, result: groupId } = await os.select({
title: i18n.ts.group,
items: groups.map((group) => ({
value: group.id,
text: group.name,
})),
});
if (canceled) return;
os.apiWithDialog("users/groups/invite", {
groupId: groupId,
userId: user.id,
});
}
async function toggleMute() { async function toggleMute() {
if (magTransProperty(user, "mute", "isMuted")) { if (magTransProperty(user, "mute", "isMuted")) {
os.apiWithDialog("mute/delete", { os.apiWithDialog("mute/delete", {
@ -304,14 +281,6 @@ export function getUserMenu(
text: i18n.ts.addToList, text: i18n.ts.addToList,
action: pushList, action: pushList,
}, },
meId !== user.id
? {
icon: "ph-users-three ph-bold ph-lg",
text: i18n.ts.inviteToGroup,
action: inviteGroup,
}
: undefined,
null,
{ {
icon: magTransProperty(user, "mute_renotes", "isRenoteMuted") icon: magTransProperty(user, "mute_renotes", "isRenoteMuted")
? "ph-eye ph-bold ph-lg" ? "ph-eye ph-bold ph-lg"

View File

@ -136,11 +136,11 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineAsyncComponent, provide, onMounted, computed, ref } from "vue";
import XCommon from "./_common_/common.vue";
import * as Acct from "calckey-js/built/acct";
import type { ComputedRef } from "vue"; import type { ComputedRef } from "vue";
import { computed, defineAsyncComponent, onMounted, provide, ref } from "vue";
import XCommon from "./_common_/common.vue";
import type { PageMetadata } from "@/scripts/page-metadata"; import type { PageMetadata } from "@/scripts/page-metadata";
import { provideMetadataReceiver } from "@/scripts/page-metadata";
import { instanceName, ui } from "@/config"; import { instanceName, ui } from "@/config";
import XDrawerMenu from "@/ui/_common_/navbar-for-mobile.vue"; import XDrawerMenu from "@/ui/_common_/navbar-for-mobile.vue";
import XSidebar from "@/ui/_common_/navbar.vue"; import XSidebar from "@/ui/_common_/navbar.vue";
@ -150,10 +150,6 @@ import { navbarItemDef } from "@/navbar";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { $i } from "@/account"; import { $i } from "@/account";
import { mainRouter } from "@/router"; import { mainRouter } from "@/router";
import {
provideMetadataReceiver,
setPageMetadata,
} from "@/scripts/page-metadata";
import { deviceKind } from "@/scripts/device-kind"; import { deviceKind } from "@/scripts/device-kind";
import { search } from "@/scripts/search"; import { search } from "@/scripts/search";
@ -243,63 +239,6 @@ if (defaultStore.state.widgets.length === 0) {
]); ]);
} }
function messagingStart(ev) {
os.popupMenu(
[
{
text: i18n.ts.messagingWithUser,
icon: "ph-user ph-bold ph-lg",
action: () => {
startUser();
},
},
{
text: i18n.ts.messagingWithGroup,
icon: "ph-users-three ph-bold ph-lg",
action: () => {
startGroup();
},
},
{
text: i18n.ts.manageGroups,
icon: "ph-user-circle-gear ph-bold ph-lg",
action: () => {
mainRouter.push("/my/groups");
},
},
],
ev.currentTarget ?? ev.target
);
}
async function startUser(): void {
os.selectUser().then((user) => {
mainRouter.push(`/my/messaging/${Acct.toString(user)}`);
});
}
async function startGroup(): void {
const groups1 = await os.api("users/groups/owned");
const groups2 = await os.api("users/groups/joined");
if (groups1.length === 0 && groups2.length === 0) {
os.alert({
type: "warning",
title: i18n.ts.youHaveNoGroups,
text: i18n.ts.joinOrCreateGroup,
});
return;
}
const { canceled, result: group } = await os.select({
title: i18n.ts.group,
items: groups1.concat(groups2).map((group) => ({
value: group,
text: group.name,
})),
});
if (canceled) return;
mainRouter.push(`/my/messaging/group/${group.id}`);
}
onMounted(() => { onMounted(() => {
if (!isDesktop.value) { if (!isDesktop.value) {
matchMedia(`(min-width: ${DESKTOP_THRESHOLD - 1}px)`).onchange = ( matchMedia(`(min-width: ${DESKTOP_THRESHOLD - 1}px)`).onchange = (

View File

@ -3,38 +3,38 @@
*/ */
declare let self: ServiceWorkerGlobalScope; declare let self: ServiceWorkerGlobalScope;
import {swLang} from "@/scripts/lang"; import { swLang } from "@/scripts/lang";
import {cli} from "@/scripts/operations"; import { cli } from "@/scripts/operations";
import {pushNotificationDataMap} from "@/types"; import { pushNotificationDataMap } from "@/types";
import getUserName from "@/scripts/get-user-name"; import getUserName from "@/scripts/get-user-name";
import {I18n} from "@/scripts/i18n"; import { I18n } from "@/scripts/i18n";
import {getAccountFromId} from "@/scripts/get-account-from-id"; import { getAccountFromId } from "@/scripts/get-account-from-id";
import * as url from "@/scripts/url"; import * as url from "@/scripts/url";
const iconUrl = (name: string) => const iconUrl = (name: string) =>
`/static-assets/notification-badges/${name}.png`; `/static-assets/notification-badges/${name}.png`;
export async function createNotification< export async function createNotification<
K extends keyof pushNotificationDataMap, K extends keyof pushNotificationDataMap
>(data: pushNotificationDataMap[K]) { >(data: pushNotificationDataMap[K]) {
const n = await composeNotification(data); const n = await composeNotification(data);
if (n) { if (n) {
return self.registration.showNotification(...n); return self.registration.showNotification(...n);
} else { } else {
console.error("Could not compose notification", data); console.error("Could not compose notification", data);
return createEmptyNotification(); return createEmptyNotification();
} }
} }
async function composeNotification<K extends keyof pushNotificationDataMap>( async function composeNotification<K extends keyof pushNotificationDataMap>(
data: pushNotificationDataMap[K], data: pushNotificationDataMap[K]
): Promise<[string, NotificationOptions] | null> { ): Promise<[string, NotificationOptions] | null> {
if (!swLang.i18n) swLang.fetchLocale(); if (!swLang.i18n) swLang.fetchLocale();
const i18n = (await swLang.i18n) as I18n<any>; const i18n = (await swLang.i18n) as I18n<any>;
const { t } = i18n; const { t } = i18n;
switch (data.type) { switch (data.type) {
/* /*
case 'driveFileCreated': // TODO (Server Side) case 'driveFileCreated': // TODO (Server Side)
return [t('_notification.fileUploaded'), { return [t('_notification.fileUploaded'), {
body: body.name, body: body.name,
@ -42,300 +42,278 @@ async function composeNotification<K extends keyof pushNotificationDataMap>(
data data
}]; }];
*/ */
case "notification": case "notification":
switch (data.body.type) { switch (data.body.type) {
case "follow": { case "follow": {
// users/showの型定義をswos.apiへ当てはめるのが困難なのでapiFetch.requestを直接使用 // users/showの型定義をswos.apiへ当てはめるのが困難なのでapiFetch.requestを直接使用
const account = await getAccountFromId(data.userId); const account = await getAccountFromId(data.userId);
if (!account) return null; if (!account) return null;
const userDetail = await cli.request( const userDetail = await cli.request(
"users/show", "users/show",
{ userId: data.body.userId }, { userId: data.body.userId },
account.token, account.token
); );
return [ return [
t("_notification.youWereFollowed"), t("_notification.youWereFollowed"),
{ {
body: getUserName(data.body.user), body: getUserName(data.body.user),
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("user-plus"), badge: iconUrl("user-plus"),
data, data,
actions: userDetail.isFollowing actions: userDetail.isFollowing
? [] ? []
: [ : [
{ {
action: "follow", action: "follow",
title: t("_notification._actions.followBack"), title: t("_notification._actions.followBack"),
}, },
], ],
}, },
]; ];
} }
case "mention": case "mention":
return [ return [
t("_notification.youGotMention", { t("_notification.youGotMention", {
name: getUserName(data.body.user), name: getUserName(data.body.user),
}), }),
{ {
body: data.body.note.text || "", body: data.body.note.text || "",
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("at"), badge: iconUrl("at"),
data, data,
actions: [ actions: [
{ {
action: "reply", action: "reply",
title: t("_notification._actions.reply"), title: t("_notification._actions.reply"),
}, },
], ],
}, },
]; ];
case "reply": case "reply":
return [ return [
t("_notification.youGotReply", { t("_notification.youGotReply", {
name: getUserName(data.body.user), name: getUserName(data.body.user),
}), }),
{ {
body: data.body.note.text || "", body: data.body.note.text || "",
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("reply"), badge: iconUrl("reply"),
data, data,
actions: [ actions: [
{ {
action: "reply", action: "reply",
title: t("_notification._actions.reply"), title: t("_notification._actions.reply"),
}, },
], ],
}, },
]; ];
case "renote": case "renote":
return [ return [
t("_notification.youRenoted", { t("_notification.youRenoted", {
name: getUserName(data.body.user), name: getUserName(data.body.user),
}), }),
{ {
body: data.body.note.text || "", body: data.body.note.text || "",
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("retweet"), badge: iconUrl("retweet"),
data, data,
actions: [ actions: [
{ {
action: "showUser", action: "showUser",
title: getUserName(data.body.user), title: getUserName(data.body.user),
}, },
], ],
}, },
]; ];
case "quote": case "quote":
return [ return [
t("_notification.youGotQuote", { t("_notification.youGotQuote", {
name: getUserName(data.body.user), name: getUserName(data.body.user),
}), }),
{ {
body: data.body.note.text || "", body: data.body.note.text || "",
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("quote-right"), badge: iconUrl("quote-right"),
data, data,
actions: [ actions: [
{ {
action: "reply", action: "reply",
title: t("_notification._actions.reply"), title: t("_notification._actions.reply"),
}, },
...(data.body.note.visibility === "public" || ...(data.body.note.visibility === "public" ||
data.body.note.visibility === "home" data.body.note.visibility === "home"
? [ ? [
{ {
action: "renote", action: "renote",
title: t("_notification._actions.renote"), title: t("_notification._actions.renote"),
}, },
] ]
: []), : []),
], ],
}, },
]; ];
case "reaction": { case "reaction": {
let reaction = data.body.reaction; let reaction = data.body.reaction;
let badge: string | undefined; let badge: string | undefined;
if (reaction.startsWith(":")) { if (reaction.startsWith(":")) {
// カスタム絵文字の場合 // カスタム絵文字の場合
const customEmoji = data.body.note.emojis.find( const customEmoji = data.body.note.emojis.find(
(x) => x.name === reaction.substr(1, reaction.length - 2), (x) => x.name === reaction.substr(1, reaction.length - 2)
); );
if (customEmoji) { if (customEmoji) {
if (reaction.includes("@")) { if (reaction.includes("@")) {
reaction = `:${reaction.substr(1, reaction.indexOf("@") - 1)}:`; reaction = `:${reaction.substr(1, reaction.indexOf("@") - 1)}:`;
} }
const u = new URL(customEmoji.url); const u = new URL(customEmoji.url);
if (u.href.startsWith(`${origin}/proxy/`)) { if (u.href.startsWith(`${origin}/proxy/`)) {
// もう既にproxyっぽそうだったらsearchParams付けるだけ // もう既にproxyっぽそうだったらsearchParams付けるだけ
u.searchParams.set("badge", "1"); u.searchParams.set("badge", "1");
badge = u.href; badge = u.href;
} else { } else {
const dummy = `${u.host}${u.pathname}`; // 拡張子がないとキャッシュしてくれないCDNがあるので const dummy = `${u.host}${u.pathname}`; // 拡張子がないとキャッシュしてくれないCDNがあるので
badge = `${origin}/proxy/${dummy}?${url.query({ badge = `${origin}/proxy/${dummy}?${url.query({
url: u.href, url: u.href,
badge: "1", badge: "1",
})}`; })}`;
} }
} }
} }
if ( if (
badge badge
? await fetch(badge) ? await fetch(badge)
.then((res) => res.status !== 200) .then((res) => res.status !== 200)
.catch(() => true) .catch(() => true)
: true : true
) { ) {
badge = iconUrl("plus"); badge = iconUrl("plus");
} }
return [ return [
`${reaction} ${getUserName(data.body.user)}`, `${reaction} ${getUserName(data.body.user)}`,
{ {
body: data.body.note.text || "", body: data.body.note.text || "",
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge, badge,
data, data,
actions: [ actions: [
{ {
action: "showUser", action: "showUser",
title: getUserName(data.body.user), title: getUserName(data.body.user),
}, },
], ],
}, },
]; ];
} }
case "pollVote": case "pollVote":
return [ return [
t("_notification.youGotPoll", { t("_notification.youGotPoll", {
name: getUserName(data.body.user), name: getUserName(data.body.user),
}), }),
{ {
body: data.body.note.text || "", body: data.body.note.text || "",
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("poll-h"), badge: iconUrl("poll-h"),
data, data,
}, },
]; ];
case "pollEnded": case "pollEnded":
return [ return [
t("_notification.pollEnded"), t("_notification.pollEnded"),
{ {
body: data.body.note.text || "", body: data.body.note.text || "",
badge: iconUrl("clipboard-check-solid"), badge: iconUrl("clipboard-check-solid"),
data, data,
}, },
]; ];
case "receiveFollowRequest": case "receiveFollowRequest":
return [ return [
t("_notification.youReceivedFollowRequest"), t("_notification.youReceivedFollowRequest"),
{ {
body: getUserName(data.body.user), body: getUserName(data.body.user),
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("clock"), badge: iconUrl("clock"),
data, data,
actions: [ actions: [
{ {
action: "accept", action: "accept",
title: t("accept"), title: t("accept"),
}, },
{ {
action: "reject", action: "reject",
title: t("reject"), title: t("reject"),
}, },
], ],
}, },
]; ];
case "followRequestAccepted": case "followRequestAccepted":
return [ return [
t("_notification.yourFollowRequestAccepted"), t("_notification.yourFollowRequestAccepted"),
{ {
body: getUserName(data.body.user), body: getUserName(data.body.user),
icon: data.body.user.avatarUrl, icon: data.body.user.avatarUrl,
badge: iconUrl("check"), badge: iconUrl("check"),
data, data,
}, },
]; ];
case "groupInvited": case "app":
return [ return [
t("_notification.youWereInvitedToGroup", { data.body.header || data.body.body,
userName: getUserName(data.body.user), {
}), body: data.body.header && data.body.body,
{ icon: data.body.icon,
body: data.body.invitation.group.name, data,
badge: iconUrl("id-card-alt"), },
data, ];
actions: [
{
action: "accept",
title: t("accept"),
},
{
action: "reject",
title: t("reject"),
},
],
},
];
case "app": default:
return [ return null;
data.body.header || data.body.body, }
{ default:
body: data.body.header && data.body.body, return null;
icon: data.body.icon, }
data,
},
];
default:
return null;
}
default:
return null;
}
} }
export async function createEmptyNotification() { export async function createEmptyNotification() {
return new Promise<void>(async (res) => { return new Promise<void>(async (res) => {
if (!swLang.i18n) swLang.fetchLocale(); if (!swLang.i18n) swLang.fetchLocale();
const i18n = (await swLang.i18n) as I18n<any>; const i18n = (await swLang.i18n) as I18n<any>;
const { t } = i18n; const { t } = i18n;
await self.registration.showNotification( await self.registration.showNotification(
t("_notification.emptyPushNotificationMessage"), t("_notification.emptyPushNotificationMessage"),
{ {
silent: true, silent: true,
badge: iconUrl("null"), badge: iconUrl("null"),
tag: "read_notification", tag: "read_notification",
}, }
); );
res(); res();
setTimeout(async () => { setTimeout(async () => {
for (const n of [ for (const n of [
...(await self.registration.getNotifications({ ...(await self.registration.getNotifications({
tag: "user_visible_auto_notification", tag: "user_visible_auto_notification",
})), })),
...(await self.registration.getNotifications({ ...(await self.registration.getNotifications({
tag: "read_notification", tag: "read_notification",
})), })),
]) { ]) {
n.close(); n.close();
} }
}, 1000); }, 1000);
}); });
} }

View File

@ -1,8 +1,6 @@
declare let self: ServiceWorkerGlobalScope; declare let self: ServiceWorkerGlobalScope;
import { import { createEmptyNotification } from "@/scripts/create-notification";
createEmptyNotification,
} from "@/scripts/create-notification";
import { swLang } from "@/scripts/lang"; import { swLang } from "@/scripts/lang";
import { swNotificationRead } from "@/scripts/notification-read"; import { swNotificationRead } from "@/scripts/notification-read";
import { pushNotificationDataMap } from "@/types"; import { pushNotificationDataMap } from "@/types";
@ -10,237 +8,224 @@ import * as swos from "@/scripts/operations";
import { acct as getAcct } from "@/filters/user"; import { acct as getAcct } from "@/filters/user";
self.addEventListener("install", (ev) => { self.addEventListener("install", (ev) => {
ev.waitUntil(self.skipWaiting()); ev.waitUntil(self.skipWaiting());
}); });
self.addEventListener("activate", (ev) => { self.addEventListener("activate", (ev) => {
ev.waitUntil( ev.waitUntil(
caches caches
.keys() .keys()
.then((cacheNames) => .then((cacheNames) =>
Promise.all( Promise.all(
cacheNames cacheNames
.filter((v) => v !== swLang.cacheName) .filter((v) => v !== swLang.cacheName)
.map((name) => caches.delete(name)), .map((name) => caches.delete(name))
), )
) )
.then(() => self.clients.claim()), .then(() => self.clients.claim())
); );
}); });
self.addEventListener("fetch", (ev) => { self.addEventListener("fetch", (ev) => {
let isHTMLRequest = false; let isHTMLRequest = false;
if (ev.request.headers.get("sec-fetch-dest") === "document") { if (ev.request.headers.get("sec-fetch-dest") === "document") {
isHTMLRequest = true; isHTMLRequest = true;
} else if (ev.request.headers.get("accept")?.includes("/html")) { } else if (ev.request.headers.get("accept")?.includes("/html")) {
isHTMLRequest = true; isHTMLRequest = true;
} else if (ev.request.url.endsWith("/")) { } else if (ev.request.url.endsWith("/")) {
isHTMLRequest = true; isHTMLRequest = true;
} }
if (!isHTMLRequest) return; if (!isHTMLRequest) return;
ev.respondWith( ev.respondWith(
fetch(ev.request).catch( fetch(ev.request).catch(
() => () =>
new Response(`Offline. Service Worker @${_VERSION_}`, { status: 200 }), new Response(`Offline. Service Worker @${_VERSION_}`, { status: 200 })
), )
); );
}); });
self.addEventListener("push", (ev) => { self.addEventListener("push", (ev) => {
// クライアント取得 // クライアント取得
ev.waitUntil( ev.waitUntil(
self.clients self.clients
.matchAll({ .matchAll({
includeUncontrolled: true, includeUncontrolled: true,
type: "window", type: "window",
}) })
.then( .then(
async <K extends keyof pushNotificationDataMap>( async <K extends keyof pushNotificationDataMap>(
clients: readonly WindowClient[], clients: readonly WindowClient[]
) => { ) => {
const data: pushNotificationDataMap[K] = ev.data?.json(); const data: pushNotificationDataMap[K] = ev.data?.json();
switch (data.type) { switch (data.type) {
// case 'driveFileCreated': // case 'driveFileCreated':
case "notification": case "notification":
case "readAllNotifications": case "readAllNotifications":
for (const n of await self.registration.getNotifications()) { for (const n of await self.registration.getNotifications()) {
if (n?.data?.type === "notification") n.close(); if (n?.data?.type === "notification") n.close();
} }
break; break;
case "readNotifications": case "readNotifications":
for (const n of await self.registration.getNotifications()) { for (const n of await self.registration.getNotifications()) {
if (data.body?.notificationIds?.includes(n.data.body.id)) { if (data.body?.notificationIds?.includes(n.data.body.id)) {
n.close(); n.close();
} }
} }
break; break;
} }
return createEmptyNotification(); return createEmptyNotification();
}, }
), )
); );
}); });
self.addEventListener( self.addEventListener(
"notificationclick", "notificationclick",
<K extends keyof pushNotificationDataMap>( <K extends keyof pushNotificationDataMap>(
ev: ServiceWorkerGlobalScopeEventMap["notificationclick"], ev: ServiceWorkerGlobalScopeEventMap["notificationclick"]
) => { ) => {
ev.waitUntil( ev.waitUntil(
(async () => { (async () => {
if (_DEV_) { if (_DEV_) {
console.log("notificationclick", ev.action, ev.notification.data); console.log("notificationclick", ev.action, ev.notification.data);
} }
const { action, notification } = ev; const { action, notification } = ev;
const data: pushNotificationDataMap[K] = notification.data; const data: pushNotificationDataMap[K] = notification.data;
const { userId: id } = data; const { userId: id } = data;
let client: WindowClient | null = null; let client: WindowClient | null = null;
switch (data.type) { switch (data.type) {
case "notification": case "notification":
switch (action) { switch (action) {
case "follow": case "follow":
if ("userId" in data.body) if ("userId" in data.body)
await swos.api("following/create", id, { await swos.api("following/create", id, {
userId: data.body.userId, userId: data.body.userId,
}); });
break; break;
case "showUser": case "showUser":
if ("user" in data.body) if ("user" in data.body)
client = await swos.openUser(getAcct(data.body.user), id); client = await swos.openUser(getAcct(data.body.user), id);
break; break;
case "reply": case "reply":
if ("note" in data.body) if ("note" in data.body)
client = await swos.openPost({ reply: data.body.note }, id); client = await swos.openPost({ reply: data.body.note }, id);
break; break;
case "renote": case "renote":
if ("note" in data.body) if ("note" in data.body)
await swos.api("notes/create", id, { await swos.api("notes/create", id, {
renoteId: data.body.note.id, renoteId: data.body.note.id,
}); });
break; break;
case "accept": case "accept":
switch (data.body.type) { switch (data.body.type) {
case "receiveFollowRequest": case "receiveFollowRequest":
await swos.api("following/requests/accept", id, { await swos.api("following/requests/accept", id, {
userId: data.body.userId, userId: data.body.userId,
}); });
break; break;
case "groupInvited": }
await swos.api("users/groups/invitations/accept", id, { break;
invitationId: data.body.invitation.id, case "reject":
}); switch (data.body.type) {
break; case "receiveFollowRequest":
} await swos.api("following/requests/reject", id, {
break; userId: data.body.userId,
case "reject": });
switch (data.body.type) { break;
case "receiveFollowRequest": }
await swos.api("following/requests/reject", id, { break;
userId: data.body.userId, case "showFollowRequests":
}); client = await swos.openClient(
break; "push",
case "groupInvited": "/my/follow-requests",
await swos.api("users/groups/invitations/reject", id, { id
invitationId: data.body.invitation.id, );
}); break;
break; default:
} switch (data.body.type) {
break; case "receiveFollowRequest":
case "showFollowRequests": client = await swos.openClient(
client = await swos.openClient( "push",
"push", "/my/follow-requests",
"/my/follow-requests", id
id, );
); break;
break; case "reaction":
default: client = await swos.openNote(data.body.note.id, id);
switch (data.body.type) { break;
case "receiveFollowRequest": default:
client = await swos.openClient( if ("note" in data.body) {
"push", client = await swos.openNote(data.body.note.id, id);
"/my/follow-requests", } else if ("user" in data.body) {
id, client = await swos.openUser(getAcct(data.body.user), id);
); }
break; break;
case "groupInvited": }
client = await swos.openClient("push", "/my/groups", id); }
break; break;
case "reaction": }
client = await swos.openNote(data.body.note.id, id);
break;
default:
if ("note" in data.body) {
client = await swos.openNote(data.body.note.id, id);
} else if ("user" in data.body) {
client = await swos.openUser(getAcct(data.body.user), id);
}
break;
}
}
break;
}
if (client) { if (client) {
client.focus(); client.focus();
} }
if (data.type === "notification") { if (data.type === "notification") {
swNotificationRead.then((that) => that.read(data)); swNotificationRead.then((that) => that.read(data));
} }
notification.close(); notification.close();
})(), })()
); );
}, }
); );
self.addEventListener( self.addEventListener(
"notificationclose", "notificationclose",
<K extends keyof pushNotificationDataMap>( <K extends keyof pushNotificationDataMap>(
ev: ServiceWorkerGlobalScopeEventMap["notificationclose"], ev: ServiceWorkerGlobalScopeEventMap["notificationclose"]
) => { ) => {
const data: pushNotificationDataMap[K] = ev.notification.data; const data: pushNotificationDataMap[K] = ev.notification.data;
if (data.type === "notification") { if (data.type === "notification") {
swNotificationRead.then((that) => that.read(data)); swNotificationRead.then((that) => that.read(data));
} }
}, }
); );
self.addEventListener( self.addEventListener(
"message", "message",
(ev: ServiceWorkerGlobalScopeEventMap["message"]) => { (ev: ServiceWorkerGlobalScopeEventMap["message"]) => {
ev.waitUntil( ev.waitUntil(
(async () => { (async () => {
switch (ev.data) { switch (ev.data) {
case "clear": case "clear":
// Cache Storage全削除 // Cache Storage全削除
await caches await caches
.keys() .keys()
.then((cacheNames) => .then((cacheNames) =>
Promise.all(cacheNames.map((name) => caches.delete(name))), Promise.all(cacheNames.map((name) => caches.delete(name)))
); );
return; // TODO return; // TODO
} }
if (typeof ev.data === "object") { if (typeof ev.data === "object") {
// E.g. '[object Array]' → 'array' // E.g. '[object Array]' → 'array'
const otype = Object.prototype.toString const otype = Object.prototype.toString
.call(ev.data) .call(ev.data)
.slice(8, -1) .slice(8, -1)
.toLowerCase(); .toLowerCase();
if (otype === "object") { if (otype === "object") {
if (ev.data.msg === "initialize") { if (ev.data.msg === "initialize") {
swLang.setLang(ev.data.lang); swLang.setLang(ev.data.lang);
} }
} }
} }
})(), })()
); );
}, }
); );