mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-21 23:04:49 +01:00
chore: split list_workspaces, renamed filetree, refactored fetch_users and fetch_buffers
Co-authored-by: alemi <me@alemi.dev>
This commit is contained in:
parent
6f04c38779
commit
e5fd0ca76a
21 changed files with 239 additions and 183 deletions
21
dist/java/src/mp/code/Client.java
vendored
21
dist/java/src/mp/code/Client.java
vendored
|
@ -91,17 +91,26 @@ public final class Client {
|
||||||
invite_to_workspace(this.ptr, workspaceId, user);
|
invite_to_workspace(this.ptr, workspaceId, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native String[] list_workspaces(long self, boolean owned, boolean invited) throws ConnectionRemoteException;
|
private static native String[] fetch_owned_workspaces(long self) throws ConnectionRemoteException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists available workspaces according to certain filters.
|
* Lists workspaces owned by the current user.
|
||||||
* @param owned if owned workspaces should be included
|
|
||||||
* @param invited if workspaces the user is invited to should be included
|
|
||||||
* @return an array of workspace IDs
|
* @return an array of workspace IDs
|
||||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||||
*/
|
*/
|
||||||
public String[] listWorkspaces(boolean owned, boolean invited) throws ConnectionRemoteException {
|
public String[] fetchOwnedWorkspaces() throws ConnectionRemoteException {
|
||||||
return list_workspaces(this.ptr, owned, invited);
|
return fetch_owned_workspaces(this.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native String[] fetch_joined_workspaces(long self) throws ConnectionRemoteException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists workspaces the current user has joined.
|
||||||
|
* @return an array of workspace IDs
|
||||||
|
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||||
|
*/
|
||||||
|
public String[] fetchJoinedWorkspaces() throws ConnectionRemoteException {
|
||||||
|
return fetch_joined_workspaces(this.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native String[] active_workspaces(long self);
|
private static native String[] active_workspaces(long self);
|
||||||
|
|
41
dist/java/src/mp/code/Workspace.java
vendored
41
dist/java/src/mp/code/Workspace.java
vendored
|
@ -1,10 +1,10 @@
|
||||||
package mp.code;
|
package mp.code;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import mp.code.data.User;
|
||||||
import mp.code.exceptions.ConnectionException;
|
import mp.code.exceptions.ConnectionException;
|
||||||
import mp.code.exceptions.ConnectionRemoteException;
|
import mp.code.exceptions.ConnectionRemoteException;
|
||||||
import mp.code.exceptions.ControllerException;
|
import mp.code.exceptions.ControllerException;
|
||||||
|
@ -57,17 +57,16 @@ public final class Workspace {
|
||||||
return Optional.ofNullable(get_buffer(this.ptr, path));
|
return Optional.ofNullable(get_buffer(this.ptr, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native String[] filetree(long self, String filter, boolean strict);
|
private static native String[] search_buffers(long self, String filter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the file tree for this workspace, optionally filtering it.
|
* Searches for buffers matching the filter in this workspace.
|
||||||
* @param filter applies an optional filter to the outputs
|
* @param filter the filter to apply
|
||||||
* @param strict whether it should be a strict match (equals) or not (startsWith)
|
|
||||||
* @return an array containing file tree as flat paths
|
* @return an array containing file tree as flat paths
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||||
public String[] filetree(Optional<String> filter, boolean strict) {
|
public String[] searchBuffers(Optional<String> filter) {
|
||||||
return filetree(this.ptr, filter.orElse(null), strict);
|
return search_buffers(this.ptr, filter.orElse(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native String[] active_buffers(long self);
|
private static native String[] active_buffers(long self);
|
||||||
|
@ -125,37 +124,39 @@ public final class Workspace {
|
||||||
return detach_buffer(this.ptr, path);
|
return detach_buffer(this.ptr, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void fetch_buffers(long self) throws ConnectionRemoteException;
|
private static native String[] fetch_buffers(long self) throws ConnectionRemoteException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the local list of buffers.
|
* Updates and fetches the local list of buffers.
|
||||||
|
* @return the updated list
|
||||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||||
*/
|
*/
|
||||||
public void fetchBuffers() throws ConnectionRemoteException {
|
public String[] fetchBuffers() throws ConnectionRemoteException {
|
||||||
fetch_buffers(this.ptr);
|
return fetch_buffers(this.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void fetch_users(long self) throws ConnectionRemoteException;
|
private static native User[] fetch_users(long self) throws ConnectionRemoteException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the local list of users.
|
* Updates and fetches the local list of users.
|
||||||
|
* @return the updated list
|
||||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||||
*/
|
*/
|
||||||
public void fetchUsers() throws ConnectionRemoteException {
|
public User[] fetchUsers() throws ConnectionRemoteException {
|
||||||
fetch_buffers(this.ptr);
|
return fetch_users(this.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native UUID[] list_buffer_users(long self, String path) throws ConnectionRemoteException;
|
private static native User[] fetch_buffer_users(long self, String path) throws ConnectionRemoteException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists the user attached to a certain buffer.
|
* Fetches the users attached to a certain buffer.
|
||||||
* The user must be attached to the buffer to perform this operation.
|
* The user must be attached to the buffer to perform this operation.
|
||||||
* @param path the path of the buffer to search
|
* @param path the path of the buffer to search
|
||||||
* @return an array of user {@link UUID UUIDs}
|
* @return an array of {@link User}s
|
||||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server, or the user wasn't attached
|
* @throws ConnectionRemoteException if an error occurs in communicating with the server, or the user wasn't attached
|
||||||
*/
|
*/
|
||||||
public UUID[] listBufferUsers(String path) throws ConnectionRemoteException {
|
public User[] fetchBufferUsers(String path) throws ConnectionRemoteException {
|
||||||
return list_buffer_users(this.ptr, path);
|
return fetch_buffer_users(this.ptr, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void delete_buffer(long self, String path) throws ConnectionRemoteException;
|
private static native void delete_buffer(long self, String path) throws ConnectionRemoteException;
|
||||||
|
|
33
dist/lua/annotations.lua
vendored
33
dist/lua/annotations.lua
vendored
|
@ -158,6 +158,17 @@ function MaybeBufferUpdatePromise:cancel() end
|
||||||
---invoke callback asynchronously as soon as promise is ready
|
---invoke callback asynchronously as soon as promise is ready
|
||||||
function MaybeBufferUpdatePromise:and_then(cb) end
|
function MaybeBufferUpdatePromise:and_then(cb) end
|
||||||
|
|
||||||
|
---@class (exact) UserListPromise : Promise
|
||||||
|
local UserListPromise = {}
|
||||||
|
--- block until promise is ready and return value
|
||||||
|
--- @return User[]
|
||||||
|
function UserListPromise:await() end
|
||||||
|
--- cancel promise execution
|
||||||
|
function UserListPromise:cancel() end
|
||||||
|
---@param cb fun(x: User[]) callback to invoke
|
||||||
|
---invoke callback asynchronously as soon as promise is ready
|
||||||
|
function UserListPromise:and_then(cb) end
|
||||||
|
|
||||||
-- [[ END ASYNC STUFF ]]
|
-- [[ END ASYNC STUFF ]]
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,13 +223,17 @@ function Client:delete_workspace(ws) end
|
||||||
---grant user acccess to workspace
|
---grant user acccess to workspace
|
||||||
function Client:invite_to_workspace(ws, user) end
|
function Client:invite_to_workspace(ws, user) end
|
||||||
|
|
||||||
---@param owned boolean? list owned workspaces, default true
|
|
||||||
---@param invited boolean? list invited workspaces, default true
|
|
||||||
---@return StringArrayPromise
|
---@return StringArrayPromise
|
||||||
---@async
|
---@async
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---grant user acccess to workspace
|
---fetch and list owned workspaces
|
||||||
function Client:list_workspaces(owned, invited) end
|
function Client:fetch_owned_workspaces() end
|
||||||
|
|
||||||
|
---@return StringArrayPromise
|
||||||
|
---@async
|
||||||
|
---@nodiscard
|
||||||
|
---fetch and list joined workspaces
|
||||||
|
function Client:fetch_joined_workspaces() end
|
||||||
|
|
||||||
---@param ws string workspace id to get
|
---@param ws string workspace id to get
|
||||||
---@return Workspace?
|
---@return Workspace?
|
||||||
|
@ -281,10 +296,9 @@ function Workspace:attach_buffer(path) end
|
||||||
function Workspace:detach_buffer(path) end
|
function Workspace:detach_buffer(path) end
|
||||||
|
|
||||||
---@param filter? string apply a filter to the return elements
|
---@param filter? string apply a filter to the return elements
|
||||||
---@param strict? boolean whether to strictly match or just check whether it starts with it
|
|
||||||
---@return string[]
|
---@return string[]
|
||||||
---return the list of available buffers in this workspace, as relative paths from workspace root
|
---return the list of available buffers in this workspace, as relative paths from workspace root
|
||||||
function Workspace:filetree(filter, strict) end
|
function Workspace:search_buffers(filter) end
|
||||||
|
|
||||||
---@return User[]
|
---@return User[]
|
||||||
---return all names of users currently in this workspace
|
---return all names of users currently in this workspace
|
||||||
|
@ -302,6 +316,13 @@ function Workspace:fetch_buffers(path) end
|
||||||
---force refresh users list from workspace
|
---force refresh users list from workspace
|
||||||
function Workspace:fetch_users(path) end
|
function Workspace:fetch_users(path) end
|
||||||
|
|
||||||
|
---@param path string the buffer to look in
|
||||||
|
---@return UserListPromise
|
||||||
|
---@async
|
||||||
|
---@nodiscard
|
||||||
|
---fetch the list of users in the given buffer
|
||||||
|
function Workspace:fetch_buffer_users(path) end
|
||||||
|
|
||||||
---@class (exact) WorkspaceEvent
|
---@class (exact) WorkspaceEvent
|
||||||
---@field type string
|
---@field type string
|
||||||
---@field value string
|
---@field value string
|
||||||
|
|
11
dist/py/src/codemp/codemp.pyi
vendored
11
dist/py/src/codemp/codemp.pyi
vendored
|
@ -51,7 +51,8 @@ class Client:
|
||||||
def create_workspace(self, workspace: str) -> Promise[None]: ...
|
def create_workspace(self, workspace: str) -> Promise[None]: ...
|
||||||
def delete_workspace(self, workspace: str) -> Promise[None]: ...
|
def delete_workspace(self, workspace: str) -> Promise[None]: ...
|
||||||
def invite_to_workspace(self, workspace: str, username: str) -> Promise[None]: ...
|
def invite_to_workspace(self, workspace: str, username: str) -> Promise[None]: ...
|
||||||
def list_workspaces(self, owned: bool, invited: bool) -> Promise[list[str]]: ...
|
def fetch_owned_workspaces(self) -> Promise[list[str]]: ...
|
||||||
|
def fetch_joined_workspaces(self) -> Promise[list[str]]: ...
|
||||||
def leave_workspace(self, workspace: str) -> bool: ...
|
def leave_workspace(self, workspace: str) -> bool: ...
|
||||||
def get_workspace(self, id: str) -> Workspace: ...
|
def get_workspace(self, id: str) -> Workspace: ...
|
||||||
def active_workspaces(self) -> list[str]: ...
|
def active_workspaces(self) -> list[str]: ...
|
||||||
|
@ -69,16 +70,16 @@ class Workspace:
|
||||||
def create_buffer(self, path: str) -> Promise[None]: ...
|
def create_buffer(self, path: str) -> Promise[None]: ...
|
||||||
def attach_buffer(self, path: str) -> Promise[BufferController]: ...
|
def attach_buffer(self, path: str) -> Promise[BufferController]: ...
|
||||||
def detach_buffer(self, path: str) -> bool: ...
|
def detach_buffer(self, path: str) -> bool: ...
|
||||||
def fetch_buffers(self) -> Promise[None]: ...
|
def fetch_buffers(self) -> Promise[list[str]]: ...
|
||||||
def fetch_users(self) -> Promise[None]: ...
|
def fetch_users(self) -> Promise[list[User]]: ...
|
||||||
def list_buffer_users(self, path: str) -> Promise[list[str]]: ...
|
def fetch_buffer_users(self, path: str) -> Promise[list[User]]: ...
|
||||||
def delete_buffer(self, path: str) -> Promise[None]: ...
|
def delete_buffer(self, path: str) -> Promise[None]: ...
|
||||||
def id(self) -> str: ...
|
def id(self) -> str: ...
|
||||||
def cursor(self) -> CursorController: ...
|
def cursor(self) -> CursorController: ...
|
||||||
def get_buffer(self, path: str) -> Optional[BufferController]: ...
|
def get_buffer(self, path: str) -> Optional[BufferController]: ...
|
||||||
def user_list(self) -> list[User]: ...
|
def user_list(self) -> list[User]: ...
|
||||||
def active_buffers(self) -> list[str]: ...
|
def active_buffers(self) -> list[str]: ...
|
||||||
def filetree(self, filter: Optional[str], strict: bool) -> list[str]: ...
|
def search_buffers(self, filter: Optional[str]) -> list[str]: ...
|
||||||
def recv(self) -> Promise[Event]: ...
|
def recv(self) -> Promise[Event]: ...
|
||||||
def try_recv(self) -> Promise[Optional[Event]]: ...
|
def try_recv(self) -> Promise[Optional[Event]]: ...
|
||||||
def poll(self) -> Promise[None]: ...
|
def poll(self) -> Promise[None]: ...
|
||||||
|
|
|
@ -19,11 +19,9 @@ pub mod event;
|
||||||
/// data structure for remote users
|
/// data structure for remote users
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
||||||
pub use change::BufferUpdate;
|
pub use change::{BufferUpdate, TextChange};
|
||||||
pub use change::TextChange;
|
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub use controller::Controller;
|
pub use controller::{AsyncReceiver, AsyncSender, Controller};
|
||||||
pub use cursor::Cursor;
|
pub use cursor::{Cursor, Selection};
|
||||||
pub use cursor::Selection;
|
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use user::User;
|
pub use user::User;
|
||||||
|
|
|
@ -170,8 +170,11 @@ impl BufferWorker {
|
||||||
|
|
||||||
// in case we have a "replace" span
|
// in case we have a "replace" span
|
||||||
if change.is_delete() {
|
if change.is_delete() {
|
||||||
self.branch
|
self.branch.delete_without_content(
|
||||||
.delete_without_content(&mut self.oplog, self.agent_id, clip_start..clip_end);
|
&mut self.oplog,
|
||||||
|
self.agent_id,
|
||||||
|
clip_start..clip_end,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if change.is_insert() {
|
if change.is_insert() {
|
||||||
|
@ -247,7 +250,9 @@ impl BufferWorker {
|
||||||
{
|
{
|
||||||
tracing::warn!(
|
tracing::warn!(
|
||||||
"Insert span ({}, {}) differs from effective content len ({})",
|
"Insert span ({}, {}) differs from effective content len ({})",
|
||||||
dtop.start(), dtop.end(), dtop.content_as_str().unwrap_or_default().len()
|
dtop.start(),
|
||||||
|
dtop.end(),
|
||||||
|
dtop.content_as_str().unwrap_or_default().len()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
crate::api::BufferUpdate {
|
crate::api::BufferUpdate {
|
||||||
|
|
|
@ -130,9 +130,18 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List all available workspaces, also filtering between those owned and those invited to.
|
/// Fetch the names of all workspaces owned by the current user.
|
||||||
pub async fn list_workspaces(&self, owned: bool, invited: bool) -> RemoteResult<Vec<String>> {
|
pub async fn fetch_owned_workspaces(&self) -> RemoteResult<Vec<String>> {
|
||||||
let mut workspaces = self
|
self.fetch_workspaces(true).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetch the names of all workspaces the current user has joined.
|
||||||
|
pub async fn fetch_joined_workspaces(&self) -> RemoteResult<Vec<String>> {
|
||||||
|
self.fetch_workspaces(false).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fetch_workspaces(&self, owned: bool) -> RemoteResult<Vec<String>> {
|
||||||
|
let workspaces = self
|
||||||
.0
|
.0
|
||||||
.session
|
.session
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -140,20 +149,18 @@ impl Client {
|
||||||
.await?
|
.await?
|
||||||
.into_inner();
|
.into_inner();
|
||||||
|
|
||||||
let mut out = Vec::new();
|
|
||||||
|
|
||||||
if owned {
|
if owned {
|
||||||
out.append(&mut workspaces.owned)
|
Ok(workspaces.owned)
|
||||||
|
} else {
|
||||||
|
Ok(workspaces.invited)
|
||||||
}
|
}
|
||||||
if invited {
|
|
||||||
out.append(&mut workspaces.invited)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(out)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join and return a [`Workspace`].
|
/// Join and return a [`Workspace`].
|
||||||
pub async fn attach_workspace(&self, workspace: impl AsRef<str>) -> ConnectionResult<Workspace> {
|
pub async fn attach_workspace(
|
||||||
|
&self,
|
||||||
|
workspace: impl AsRef<str>,
|
||||||
|
) -> ConnectionResult<Workspace> {
|
||||||
let token = self
|
let token = self
|
||||||
.0
|
.0
|
||||||
.session
|
.session
|
||||||
|
|
|
@ -2,10 +2,7 @@ use jni::{objects::JObject, JNIEnv};
|
||||||
use jni_toolbox::jni;
|
use jni_toolbox::jni;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::{AsyncReceiver, AsyncSender, BufferUpdate, TextChange},
|
||||||
controller::{AsyncReceiver, AsyncSender},
|
|
||||||
BufferUpdate, TextChange,
|
|
||||||
},
|
|
||||||
errors::ControllerError,
|
errors::ControllerError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,14 +46,16 @@ fn invite_to_workspace(
|
||||||
super::tokio().block_on(client.invite_to_workspace(workspace, user))
|
super::tokio().block_on(client.invite_to_workspace(workspace, user))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List available workspaces.
|
/// List owned workspaces.
|
||||||
#[jni(package = "mp.code", class = "Client")]
|
#[jni(package = "mp.code", class = "Client")]
|
||||||
fn list_workspaces(
|
fn fetch_owned_workspaces(client: &mut Client) -> Result<Vec<String>, RemoteError> {
|
||||||
client: &mut Client,
|
super::tokio().block_on(client.fetch_owned_workspaces())
|
||||||
owned: bool,
|
}
|
||||||
invited: bool,
|
|
||||||
) -> Result<Vec<String>, RemoteError> {
|
/// List joined workspaces.
|
||||||
super::tokio().block_on(client.list_workspaces(owned, invited))
|
#[jni(package = "mp.code", class = "Client")]
|
||||||
|
fn fetch_joined_workspaces(client: &mut Client) -> Result<Vec<String>, RemoteError> {
|
||||||
|
super::tokio().block_on(client.fetch_joined_workspaces())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List available workspaces.
|
/// List available workspaces.
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::{AsyncReceiver, AsyncSender, Cursor, Selection},
|
||||||
controller::{AsyncReceiver, AsyncSender},
|
|
||||||
Cursor, Selection,
|
|
||||||
},
|
|
||||||
errors::ControllerError,
|
errors::ControllerError,
|
||||||
};
|
};
|
||||||
use jni::{objects::JObject, JNIEnv};
|
use jni::{objects::JObject, JNIEnv};
|
||||||
|
|
|
@ -25,10 +25,10 @@ fn get_buffer(workspace: &mut Workspace, path: String) -> Option<crate::buffer::
|
||||||
workspace.get_buffer(&path)
|
workspace.get_buffer(&path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the filetree.
|
/// Searches for buffers matching the filter.
|
||||||
#[jni(package = "mp.code", class = "Workspace")]
|
#[jni(package = "mp.code", class = "Workspace")]
|
||||||
fn filetree(workspace: &mut Workspace, filter: Option<String>, strict: bool) -> Vec<String> {
|
fn search_buffers(workspace: &mut Workspace, filter: Option<String>) -> Vec<String> {
|
||||||
workspace.filetree(filter.as_deref(), strict)
|
workspace.search_buffers(filter.as_deref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a list of the active buffers.
|
/// Gets a list of the active buffers.
|
||||||
|
@ -66,23 +66,23 @@ fn detach_buffer(workspace: &mut Workspace, path: String) -> bool {
|
||||||
|
|
||||||
/// Update the local buffer list.
|
/// Update the local buffer list.
|
||||||
#[jni(package = "mp.code", class = "Workspace")]
|
#[jni(package = "mp.code", class = "Workspace")]
|
||||||
fn fetch_buffers(workspace: &mut Workspace) -> Result<(), RemoteError> {
|
fn fetch_buffers(workspace: &mut Workspace) -> Result<Vec<String>, RemoteError> {
|
||||||
super::tokio().block_on(workspace.fetch_buffers())
|
super::tokio().block_on(workspace.fetch_buffers())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the local user list.
|
/// Update the local user list.
|
||||||
#[jni(package = "mp.code", class = "Workspace")]
|
#[jni(package = "mp.code", class = "Workspace")]
|
||||||
fn fetch_users(workspace: &mut Workspace) -> Result<(), RemoteError> {
|
fn fetch_users(workspace: &mut Workspace) -> Result<Vec<User>, RemoteError> {
|
||||||
super::tokio().block_on(workspace.fetch_users())
|
super::tokio().block_on(workspace.fetch_users())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List users attached to a buffer.
|
/// Fetch users attached to a buffer.
|
||||||
#[jni(package = "mp.code", class = "Workspace")]
|
#[jni(package = "mp.code", class = "Workspace")]
|
||||||
fn list_buffer_users(
|
fn fetch_buffer_users(
|
||||||
workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
path: String,
|
path: String,
|
||||||
) -> Result<Vec<crate::api::User>, RemoteError> {
|
) -> Result<Vec<crate::api::User>, RemoteError> {
|
||||||
super::tokio().block_on(workspace.list_buffer_users(&path))
|
super::tokio().block_on(workspace.fetch_buffer_users(&path))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a buffer.
|
/// Delete a buffer.
|
||||||
|
|
|
@ -46,14 +46,16 @@ impl Client {
|
||||||
Ok(self.delete_workspace(workspace).await?)
|
Ok(self.delete_workspace(workspace).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[napi(js_name = "listWorkspaces")]
|
#[napi(js_name = "fetchOwnedWorkspaces")]
|
||||||
/// list available workspaces
|
/// fetch owned workspaces
|
||||||
pub async fn js_list_workspaces(
|
pub async fn js_fetch_owned_workspaces(&self) -> napi::Result<Vec<String>> {
|
||||||
&self,
|
Ok(self.fetch_owned_workspaces().await?)
|
||||||
owned: bool,
|
}
|
||||||
invited: bool,
|
|
||||||
) -> napi::Result<Vec<String>> {
|
#[napi(js_name = "fetchJoinedWorkspaces")]
|
||||||
Ok(self.list_workspaces(owned, invited).await?)
|
/// fetch joined workspaces
|
||||||
|
pub async fn js_fetch_joined_workspaces(&self) -> napi::Result<Vec<String>> {
|
||||||
|
Ok(self.fetch_joined_workspaces().await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[napi(js_name = "inviteToWorkspace")]
|
#[napi(js_name = "inviteToWorkspace")]
|
||||||
|
|
|
@ -44,9 +44,9 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List all available buffers in this workspace
|
/// List all available buffers in this workspace
|
||||||
#[napi(js_name = "filetree")]
|
#[napi(js_name = "search_buffers")]
|
||||||
pub fn js_filetree(&self, filter: Option<&str>, strict: bool) -> Vec<String> {
|
pub fn js_search_buffers(&self, filter: Option<&str>) -> Vec<String> {
|
||||||
self.filetree(filter, strict)
|
self.search_buffers(filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List all user names currently in this workspace
|
/// List all user names currently in this workspace
|
||||||
|
@ -137,23 +137,28 @@ impl Workspace {
|
||||||
|
|
||||||
/// Re-fetch remote buffer list
|
/// Re-fetch remote buffer list
|
||||||
#[napi(js_name = "fetchBuffers")]
|
#[napi(js_name = "fetchBuffers")]
|
||||||
pub async fn js_fetch_buffers(&self) -> napi::Result<()> {
|
pub async fn js_fetch_buffers(&self) -> napi::Result<Vec<String>> {
|
||||||
Ok(self.fetch_buffers().await?)
|
Ok(self.fetch_buffers().await?)
|
||||||
}
|
}
|
||||||
/// Re-fetch the list of all users in the workspace.
|
/// Re-fetch the list of all users in the workspace.
|
||||||
#[napi(js_name = "fetchUsers")]
|
#[napi(js_name = "fetchUsers")]
|
||||||
pub async fn js_fetch_users(&self) -> napi::Result<()> {
|
pub async fn js_fetch_users(&self) -> napi::Result<Vec<JsUser>> {
|
||||||
Ok(self.fetch_users().await?)
|
Ok(self
|
||||||
|
.fetch_users()
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(JsUser::from)
|
||||||
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List users attached to a specific buffer
|
/// List users attached to a specific buffer
|
||||||
#[napi(js_name = "listBufferUsers")]
|
#[napi(js_name = "fetchBufferUsers")]
|
||||||
pub async fn js_list_buffer_users(
|
pub async fn js_fetch_buffer_users(
|
||||||
&self,
|
&self,
|
||||||
path: String,
|
path: String,
|
||||||
) -> napi::Result<Vec<crate::ffi::js::client::JsUser>> {
|
) -> napi::Result<Vec<crate::ffi::js::client::JsUser>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.list_buffer_users(&path)
|
.fetch_buffer_users(&path)
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(super::client::JsUser::from)
|
.map(super::client::JsUser::from)
|
||||||
|
|
|
@ -12,8 +12,12 @@ impl LuaUserData for CodempClient {
|
||||||
Ok(format!("{:?}", this))
|
Ok(format!("{:?}", this))
|
||||||
});
|
});
|
||||||
|
|
||||||
methods.add_method("current_user", |_, this, ()| Ok(this.current_user().clone()));
|
methods.add_method("current_user", |_, this, ()| {
|
||||||
methods.add_method("active_workspaces", |_, this, ()| Ok(this.active_workspaces()));
|
Ok(this.current_user().clone())
|
||||||
|
});
|
||||||
|
methods.add_method("active_workspaces", |_, this, ()| {
|
||||||
|
Ok(this.active_workspaces())
|
||||||
|
});
|
||||||
|
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"refresh",
|
"refresh",
|
||||||
|
@ -39,8 +43,14 @@ impl LuaUserData for CodempClient {
|
||||||
a_sync! { this => this.invite_to_workspace(ws, user).await? }
|
a_sync! { this => this.invite_to_workspace(ws, user).await? }
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("list_workspaces", |_, this, (owned,invited):(Option<bool>,Option<bool>)|
|
methods.add_method(
|
||||||
a_sync! { this => this.list_workspaces(owned.unwrap_or(true), invited.unwrap_or(true)).await? }
|
"fetch_owned_workspaces",
|
||||||
|
|_, this, ()| a_sync! { this => this.fetch_owned_workspaces().await? },
|
||||||
|
);
|
||||||
|
|
||||||
|
methods.add_method(
|
||||||
|
"fetch_joined_workspaces",
|
||||||
|
|_, this, ()| a_sync! { this => this.fetch_joined_workspaces().await? },
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method("leave_workspace", |_, this, (ws,): (String,)| {
|
methods.add_method("leave_workspace", |_, this, (ws,): (String,)| {
|
||||||
|
|
|
@ -101,6 +101,7 @@ macro_rules! callback_args {
|
||||||
callback_args! {
|
callback_args! {
|
||||||
Str: String,
|
Str: String,
|
||||||
VecStr: Vec<String>,
|
VecStr: Vec<String>,
|
||||||
|
VecUser: Vec<CodempUser>,
|
||||||
Client: CodempClient,
|
Client: CodempClient,
|
||||||
CursorController: CodempCursorController,
|
CursorController: CodempCursorController,
|
||||||
BufferController: CodempBufferController,
|
BufferController: CodempBufferController,
|
||||||
|
|
|
@ -43,12 +43,15 @@ impl LuaUserData for CodempWorkspace {
|
||||||
|_, this, ()| a_sync! { this => this.fetch_users().await? },
|
|_, this, ()| a_sync! { this => this.fetch_users().await? },
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_method(
|
methods.add_method("search_buffers", |_, this, (filter,): (Option<String>,)| {
|
||||||
"filetree",
|
Ok(this.search_buffers(filter.as_deref()))
|
||||||
|_, this, (filter, strict): (Option<String>, Option<bool>)| {
|
});
|
||||||
Ok(this.filetree(filter.as_deref(), strict.unwrap_or(false)))
|
|
||||||
},
|
methods.add_method("fetch_buffer_users", |_, this, (path,): (String,)| {
|
||||||
);
|
a_sync! {
|
||||||
|
this => this.fetch_buffer_users(&path).await?
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
methods.add_method("id", |_, this, ()| Ok(this.id()));
|
methods.add_method("id", |_, this, ()| Ok(this.id()));
|
||||||
methods.add_method("cursor", |_, this, ()| Ok(this.cursor()));
|
methods.add_method("cursor", |_, this, ()| Ok(this.cursor()));
|
||||||
|
|
|
@ -55,16 +55,18 @@ impl Client {
|
||||||
a_sync_allow_threads!(py, this.invite_to_workspace(workspace, user).await)
|
a_sync_allow_threads!(py, this.invite_to_workspace(workspace, user).await)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "list_workspaces")]
|
#[pyo3(name = "fetch_owned_workspaces")]
|
||||||
fn pylist_workspaces(
|
fn pyfetch_owned_workspaces(&self, py: Python<'_>) -> PyResult<super::Promise> {
|
||||||
&self,
|
tracing::info!("attempting to fetch owned workspaces");
|
||||||
py: Python<'_>,
|
|
||||||
owned: bool,
|
|
||||||
invited: bool,
|
|
||||||
) -> PyResult<super::Promise> {
|
|
||||||
tracing::info!("attempting to list workspaces");
|
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
a_sync_allow_threads!(py, this.list_workspaces(owned, invited).await)
|
a_sync_allow_threads!(py, this.fetch_owned_workspaces().await)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyo3(name = "fetch_joined_workspaces")]
|
||||||
|
fn pyfetch_joined_workspaces(&self, py: Python<'_>) -> PyResult<super::Promise> {
|
||||||
|
tracing::info!("attempting to fetch joined workspaces");
|
||||||
|
let this = self.clone();
|
||||||
|
a_sync_allow_threads!(py, this.fetch_joined_workspaces().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "leave_workspace")]
|
#[pyo3(name = "leave_workspace")]
|
||||||
|
|
|
@ -41,11 +41,11 @@ impl Workspace {
|
||||||
a_sync_allow_threads!(py, this.fetch_users().await)
|
a_sync_allow_threads!(py, this.fetch_users().await)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "list_buffer_users")]
|
#[pyo3(name = "fetch_buffer_users")]
|
||||||
fn pylist_buffer_users(&self, py: Python, path: String) -> PyResult<Promise> {
|
fn pyfetch_buffer_users(&self, py: Python, path: String) -> PyResult<Promise> {
|
||||||
// crate::Result<Vec<crate::api::User>>
|
// crate::Result<Vec<crate::api::User>>
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
a_sync_allow_threads!(py, this.list_buffer_users(path.as_str()).await)
|
a_sync_allow_threads!(py, this.fetch_buffer_users(path.as_str()).await)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "delete_buffer")]
|
#[pyo3(name = "delete_buffer")]
|
||||||
|
@ -74,10 +74,10 @@ impl Workspace {
|
||||||
self.active_buffers()
|
self.active_buffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "filetree")]
|
#[pyo3(name = "search_buffers")]
|
||||||
#[pyo3(signature = (filter=None, strict=false))]
|
#[pyo3(signature = (filter=None))]
|
||||||
fn pyfiletree(&self, filter: Option<&str>, strict: bool) -> Vec<String> {
|
fn pysearch_buffers(&self, filter: Option<&str>) -> Vec<String> {
|
||||||
self.filetree(filter, strict)
|
self.search_buffers(filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "user_list")]
|
#[pyo3(name = "user_list")]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//! All-in-one renamed imports with `use codemp::prelude::*`.
|
//! All-in-one renamed imports with `use codemp::prelude::*`.
|
||||||
|
|
||||||
pub use crate::api::{
|
pub use crate::api::{
|
||||||
controller::AsyncReceiver as CodempAsyncReceiver, controller::AsyncSender as CodempAsyncSender,
|
AsyncReceiver as CodempAsyncReceiver, AsyncSender as CodempAsyncSender,
|
||||||
BufferUpdate as CodempBufferUpdate, Config as CodempConfig, Controller as CodempController,
|
BufferUpdate as CodempBufferUpdate, Config as CodempConfig, Controller as CodempController,
|
||||||
Cursor as CodempCursor, Event as CodempEvent, Selection as CodempSelection,
|
Cursor as CodempCursor, Event as CodempEvent, Selection as CodempSelection,
|
||||||
TextChange as CodempTextChange, User as CodempUser,
|
TextChange as CodempTextChange, User as CodempUser,
|
||||||
|
|
|
@ -26,7 +26,7 @@ use codemp_proto::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use dashmap::{DashMap, DashSet};
|
use dashmap::{DashMap, DashSet};
|
||||||
use std::{collections::BTreeSet, sync::Arc};
|
use std::sync::Arc;
|
||||||
use tokio::sync::{mpsc, mpsc::error::TryRecvError};
|
use tokio::sync::{mpsc, mpsc::error::TryRecvError};
|
||||||
use tonic::Streaming;
|
use tonic::Streaming;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -201,45 +201,48 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Re-fetch the list of available buffers in the workspace.
|
/// Re-fetch the list of available buffers in the workspace.
|
||||||
pub async fn fetch_buffers(&self) -> RemoteResult<()> {
|
pub async fn fetch_buffers(&self) -> RemoteResult<Vec<String>> {
|
||||||
let mut workspace_client = self.0.services.ws();
|
let mut workspace_client = self.0.services.ws();
|
||||||
let buffers = workspace_client
|
let resp = workspace_client
|
||||||
.list_buffers(tonic::Request::new(Empty {}))
|
.list_buffers(tonic::Request::new(Empty {}))
|
||||||
.await?
|
.await?
|
||||||
.into_inner()
|
.into_inner();
|
||||||
.buffers;
|
|
||||||
|
let mut out = Vec::new();
|
||||||
|
|
||||||
self.0.filetree.clear();
|
self.0.filetree.clear();
|
||||||
for b in buffers {
|
for b in resp.buffers {
|
||||||
self.0.filetree.insert(b.path);
|
self.0.filetree.insert(b.path.clone());
|
||||||
|
out.push(b.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Re-fetch the list of all users in the workspace.
|
/// Re-fetch the list of all users in the workspace.
|
||||||
pub async fn fetch_users(&self) -> RemoteResult<()> {
|
pub async fn fetch_users(&self) -> RemoteResult<Vec<User>> {
|
||||||
let mut workspace_client = self.0.services.ws();
|
let mut workspace_client = self.0.services.ws();
|
||||||
let users = BTreeSet::from_iter(
|
let users = workspace_client
|
||||||
workspace_client
|
|
||||||
.list_users(tonic::Request::new(Empty {}))
|
.list_users(tonic::Request::new(Empty {}))
|
||||||
.await?
|
.await?
|
||||||
.into_inner()
|
.into_inner()
|
||||||
.users
|
.users
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(User::from),
|
.map(User::from);
|
||||||
);
|
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
self.0.users.clear();
|
self.0.users.clear();
|
||||||
for u in users {
|
for u in users {
|
||||||
self.0.users.insert(u.id, u);
|
self.0.users.insert(u.id, u.clone());
|
||||||
|
result.push(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a list of the [User]s attached to a specific buffer.
|
/// Fetch a list of the [User]s attached to a specific buffer.
|
||||||
pub async fn list_buffer_users(&self, path: &str) -> RemoteResult<Vec<User>> {
|
pub async fn fetch_buffer_users(&self, path: &str) -> RemoteResult<Vec<User>> {
|
||||||
let mut workspace_client = self.0.services.ws();
|
let mut workspace_client = self.0.services.ws();
|
||||||
let buffer_users = workspace_client
|
let buffer_users = workspace_client
|
||||||
.list_buffer_users(tonic::Request::new(BufferNode {
|
.list_buffer_users(tonic::Request::new(BufferNode {
|
||||||
|
@ -311,20 +314,12 @@ impl Workspace {
|
||||||
/// Get the filetree as it is currently cached.
|
/// Get the filetree as it is currently cached.
|
||||||
/// A filter may be applied, and it may be strict (equality check) or not (starts_with check).
|
/// A filter may be applied, and it may be strict (equality check) or not (starts_with check).
|
||||||
// #[cfg_attr(feature = "js", napi)] // https://github.com/napi-rs/napi-rs/issues/1120
|
// #[cfg_attr(feature = "js", napi)] // https://github.com/napi-rs/napi-rs/issues/1120
|
||||||
pub fn filetree(&self, filter: Option<&str>, strict: bool) -> Vec<String> {
|
pub fn search_buffers(&self, filter: Option<&str>) -> Vec<String> {
|
||||||
let mut tree = self
|
let mut tree = self
|
||||||
.0
|
.0
|
||||||
.filetree
|
.filetree
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|f| {
|
.filter(|f| filter.map_or(true, |flt| f.starts_with(flt)))
|
||||||
filter.map_or(true, |flt| {
|
|
||||||
if strict {
|
|
||||||
f.as_str() == flt
|
|
||||||
} else {
|
|
||||||
f.starts_with(flt)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.map(|f| f.clone())
|
.map(|f| f.clone())
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
tree.sort();
|
tree.sort();
|
||||||
|
|
Loading…
Reference in a new issue