Add README

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent aeac1e2e36
commit 2f4d7ff73d

@ -1,27 +1,26 @@
# MediarepoUi
<h1 align="center">
mediarepo-ui
</h1>
<h3 align="center" style="color:red">This repository is a work in progress</h3>
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.9.
- - -
## Development server
This repository contains a frontend client to connect to the [mediarepo-daemon](https://github.com/Trivernis/mediarepo-daemon).
It is written in tauri (yay).
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Usage
## Code scaffolding
Refer to [the tauri documentation](https://tauri.studio/en/docs/getting-started) for information about setting up your environment to build this project.
With the `cargo-tauri` tooling installed you can run
```
cargo tauri dev
```
to start the application in development mode or
```
cargo tauri build
```
to bundle the application.
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## License
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
GPL-3

@ -1,13 +1,13 @@
use crate::commands::get_ipc;
use crate::commands::{add_once_buffer, get_ipc};
use mediarepo::requests::{FindFilesByTagsRequest, GetFileThumbnailsRequest, ReadFileRequest};
use mediarepo::responses::{FileResponse, ThumbnailResponse};
use crate::context::Context;
use crate::error::{AppError, AppResult};
use crate::error::AppResult;
#[tauri::command]
pub async fn get_all_files(context: tauri::State<'_, Context>) -> AppResult<Vec<FileResponse>> {
let ipc = get_ipc(context).await?;
let ipc = get_ipc(&context).await?;
let response = ipc
.emitter
.emit_to("files", "all_files", ())
@ -23,7 +23,7 @@ pub async fn find_files(
tags: Vec<String>,
context: tauri::State<'_, Context>,
) -> AppResult<Vec<FileResponse>> {
let ipc = get_ipc(context).await?;
let ipc = get_ipc(&context).await?;
let response = ipc
.emitter
.emit_to("files", "find_files", FindFilesByTagsRequest { tags })
@ -36,17 +36,20 @@ pub async fn find_files(
#[tauri::command]
pub async fn read_file_by_hash(
hash: String,
mime: String,
context: tauri::State<'_, Context>,
) -> AppResult<Vec<u8>> {
let ipc = get_ipc(context).await?;
) -> AppResult<String> {
let ipc = get_ipc(&context).await?;
let response = ipc
.emitter
.emit_to("files", "read_file", ReadFileRequest::Hash(hash))
.emit_to("files", "read_file", ReadFileRequest::Hash(hash.clone()))
.await?
.await_reply(&ipc)
.await?;
let raw_data = response.data_raw().to_vec();
let uri = add_once_buffer(&context, hash, mime, raw_data);
Ok(response.data_raw().to_vec())
Ok(uri)
}
#[tauri::command]
@ -54,7 +57,7 @@ pub async fn get_thumbnails(
hash: String,
context: tauri::State<'_, Context>,
) -> AppResult<Vec<ThumbnailResponse>> {
let ipc = get_ipc(context).await?;
let ipc = get_ipc(&context).await?;
let response = ipc
.emitter
.emit_to(
@ -72,19 +75,18 @@ pub async fn get_thumbnails(
#[tauri::command]
pub async fn read_thumbnail(
hash: String,
mime: String,
context: tauri::State<'_, Context>,
) -> AppResult<Vec<u8>> {
let ipc = context.ipc.read().await;
if let Some(ipc) = &*ipc {
) -> AppResult<String> {
let ipc = get_ipc(&context).await?;
let response = ipc
.emitter
.emit_to("files", "read_thumbnail", hash)
.emit_to("files", "read_thumbnail", hash.clone())
.await?
.await_reply(&ipc)
.await?;
let raw_data = response.data_raw().to_vec();
let uri = add_once_buffer(&context, hash, mime, raw_data);
Ok(response.data_raw().to_vec())
} else {
Err(AppError::new("No ipc connection."))
}
Ok(uri)
}

@ -1,6 +1,6 @@
use rmp_ipc::ipc::context::Context as IPCContext;
use crate::context::Context;
use crate::context::{Context, OnceBuffer};
use crate::error::{AppError, AppResult};
pub mod files;
@ -20,7 +20,22 @@ pub async fn emit_info(context: tauri::State<'_, Context>) -> AppResult<()> {
Ok(())
}
pub async fn get_ipc(context: tauri::State<'_, Context>) -> AppResult<IPCContext> {
pub async fn get_ipc(context: &tauri::State<'_, Context>) -> AppResult<IPCContext> {
let ipc = context.ipc.read().await;
(ipc.clone()).ok_or(AppError::new("No ipc connection."))
}
/// Adds a once-buffer to the buffer store
pub fn add_once_buffer(
context: &tauri::State<'_, Context>,
key: String,
mime: String,
buf: Vec<u8>,
) -> String {
let uri = format!("once://{}", key);
let once_buffer = OnceBuffer { mime, buf };
let mut once_buffers = context.once_buffers.lock().unwrap();
once_buffers.insert(key, once_buffer);
uri
}

@ -9,7 +9,7 @@ pub async fn get_tags_for_file(
hash: String,
context: tauri::State<'_, Context>,
) -> AppResult<Vec<TagResponse>> {
let ipc = get_ipc(context).await?;
let ipc = get_ipc(&context).await?;
let response = ipc
.emitter
.emit_to("tags", "tags_for_file", FileIdentifier::Hash(hash))

@ -1,14 +1,22 @@
use crate::commands::repo::Repository;
use crate::settings::Settings;
use rmp_ipc::ipc::context::Context as IPCContext;
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::Mutex as StdMutex;
use tokio::sync::RwLock;
pub struct OnceBuffer {
pub mime: String,
pub buf: Vec<u8>,
}
#[derive(Clone)]
pub struct Context {
pub active_repository: Arc<RwLock<Option<Repository>>>,
pub ipc: Arc<RwLock<Option<IPCContext>>>,
pub settings: Arc<RwLock<Settings>>,
pub once_buffers: Arc<StdMutex<HashMap<String, OnceBuffer>>>,
}
impl Context {
@ -17,6 +25,7 @@ impl Context {
ipc: Arc::new(RwLock::new(None)),
active_repository: Arc::new(RwLock::new(None)),
settings: Arc::new(RwLock::new(settings)),
once_buffers: Arc::new(StdMutex::new(HashMap::new())),
}
}
}

@ -11,6 +11,8 @@ use crate::commands::repo::{
use crate::commands::tags::*;
use crate::context::Context;
use crate::settings::load_settings;
use tauri::http::ResponseBuilder;
use tauri::Manager;
mod commands;
pub mod context;
@ -24,6 +26,25 @@ fn main() {
tauri::Builder::default()
.manage(context)
.register_uri_scheme_protocol("once", |app, request| {
let context = app.state::<Context>();
let resource_key = request.uri().trim_start_matches("once://");
let buffer = {
let mut buffers = context.once_buffers.lock().unwrap();
buffers.remove(resource_key)
};
if let Some(buffer) = buffer {
ResponseBuilder::new()
.mimetype(&buffer.mime)
.status(200)
.body(buffer.buf)
} else {
ResponseBuilder::new()
.mimetype("text/plain")
.status(404)
.body("Resource not found".as_bytes().to_vec())
}
})
.invoke_handler(tauri::generate_handler![
get_repositories,
add_repository,

@ -26,18 +26,14 @@ export class FileService {
this.displayedFiles.next(files);
}
public async readFile(hash: string, mime_type: string): Promise<SafeResourceUrl> {
const data = await invoke<number[]>("read_file_by_hash", {hash});
const blob = new Blob([new Uint8Array(data)], {type: mime_type});
return this.createSafeObjectUrl(blob);
public async readFile(hash: string, mime: string): Promise<SafeResourceUrl> {
const once_uri = await invoke<string>("read_file_by_hash", {hash, mime});
return this.sanitizer.bypassSecurityTrustResourceUrl(once_uri);
}
public async readThumbnail(thumbnail: Thumbnail): Promise<SafeResourceUrl> {
let data = await invoke<number[]>("read_thumbnail", {hash: thumbnail.hash});
const blob = new Blob([new Uint8Array(data)], {type: thumbnail.mime});
return this.createSafeObjectUrl(blob);
let once_uri = await invoke<string>("read_thumbnail", {hash: thumbnail.hash, mime: thumbnail.mime});
return this.sanitizer.bypassSecurityTrustResourceUrl(once_uri);
}
public async getThumbnails(hash: string): Promise<Thumbnail[]> {

Loading…
Cancel
Save