Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lunar/.env.local
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
RELAY_API_URL=http://34.84.172.121
NEXT_PUBLIC_RELAY_API_URL=http://34.84.172.121
NEXT_PUBLIC_API_URL=http://localhost:8000
3 changes: 2 additions & 1 deletion lunar/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ tauri-build = { version = "1.5.3", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.7.0", features = [] }
tauri = { version = "1.7.0", features = ["process-command-api"] }
mega = { workspace = true }
tokio = { workspace = true }

[features]
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
Expand Down
107 changes: 97 additions & 10 deletions lunar/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,111 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use std::str::FromStr;
use std::sync::Arc;

use serde::Deserialize;
use tauri::api::process::{Command, CommandChild, CommandEvent};
use tauri::State;
use tokio::sync::Mutex;

struct ServiceState {
child: Option<CommandChild>,
}

#[derive(Debug, Deserialize, Clone)]
struct MegaStartParams {
pub bootstrap_node: String,
}

impl Default for MegaStartParams {
fn default() -> Self {
Self {
bootstrap_node: String::from_str("http://34.84.172.121/relay").unwrap(),
}
}
}

#[tauri::command]
async fn start_mega_service(
state: State<'_, Arc<Mutex<ServiceState>>>,
params: MegaStartParams,
) -> Result<(), String> {
let mut service_state = state.lock().await;
if service_state.child.is_some() {
return Err("Service is already running".into());
}

let (mut rx, child) = Command::new_sidecar("mega")
.expect("Failed to create `mega` binary command")
.args([
"service",
"http",
"--bootstrap-node",
&params.bootstrap_node,
])
.spawn()
.expect("Failed to spawn `Mega service`");

service_state.child = Some(child);

tauri::async_runtime::spawn(async move {
while let Some(event) = rx.recv().await {
if let CommandEvent::Stdout(line) = event {
print!("{}", line);
}
}
});
Ok(())
}

#[tauri::command]
fn hello_string(name: &str) -> String {
format!("Hello from Rust, {}!", name)
async fn stop_mega_service(state: State<'_, Arc<Mutex<ServiceState>>>) -> Result<(), String> {
let mut service_state = state.lock().await;
if let Some(child) = service_state.child.take() {
child.kill().map_err(|e| e.to_string())?;
} else {
println!("Mega Service is not running");
}
Ok(())
}

fn start_mega() {
let args_str = "service http --ztm agent --bootstrap-node http://34.84.172.121/relay".to_string();
let args = args_str.split(' ').collect();
mega::cli::parse(Some(args)).expect("failed to start mega");
#[tauri::command]
async fn restart_mega_service(
state: State<'_, Arc<Mutex<ServiceState>>>,
params: MegaStartParams,
) -> Result<(), String> {
stop_mega_service(state.clone()).await?;
start_mega_service(state, params).await?;
Ok(())
}

#[tauri::command]
async fn mega_service_status(state: State<'_, Arc<Mutex<ServiceState>>>) -> Result<bool, String> {
let service_state = state.lock().await;
Ok(service_state.child.is_some())
}

fn main() {
// let params = MegaStartParams::default();
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![hello_string])
.manage(Arc::new(Mutex::new(ServiceState { child: None })))
.invoke_handler(tauri::generate_handler![
start_mega_service,
stop_mega_service,
restart_mega_service,
mega_service_status
])
.setup(|_| {
std::thread::spawn(move || {
start_mega();
});
// let app_handle = app.handle();
// let state = app.state::<Arc<Mutex<ServiceState>>>().clone();
// tauri::async_runtime::spawn(async move {
// if let Err(e) = start_mega_service(state, params).await {
// eprintln!("Failed to restart rust_service: {}", e);
// } else {
// println!("Rust service restarted successfully");
// }
// });
Ok(())
})
.run(tauri::generate_context!())
Expand Down
4 changes: 2 additions & 2 deletions lunar/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@
"windows": [
{
"fullscreen": false,
"height": 600,
"height": 768,
"resizable": true,
"title": "lunar-app",
"width": 800
"width": 1366
}
]
}
Expand Down
41 changes: 14 additions & 27 deletions lunar/src/app/api/fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import useSWR from "swr";

const endpoint = process.env.NEXT_PUBLIC_API_URL;

const fetchWithToken = async (url, token) => {

return fetch(url, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
}
}).then(res => {
if (!res.ok) {
throw new Error('An error occurred while fetching the data.');
}
return res.json();
});
};
const relay = process.env.NEXT_PUBLIC_RELAY_API_URL;

export class FetchError extends Error {
info: any;
Expand All @@ -38,20 +24,10 @@ const fetcher = async url => {
return res.json()
}

export function useUser(token) {
const { data, error, isLoading } = useSWR(token ? [`${endpoint}/auth/github/user`, token] : null, ([url, token]) => fetchWithToken(url, token), {
dedupingInterval: 300000, // The request will not be repeated for 5 minutes
})
return {
user: data,
isLoading,
isError: error,
}
}

export function useTreeCommitInfo(path) {
const { data, error, isLoading } = useSWR(`${endpoint}/api/v1/tree/commit-info?path=${path}`, fetcher, {
dedupingInterval: 300000,
dedupingInterval: 60000,
})
return {
tree: data,
Expand All @@ -62,11 +38,22 @@ export function useTreeCommitInfo(path) {

export function useBlobContent(path) {
const { data, error, isLoading } = useSWR(`${endpoint}/api/v1/blob?path=${path}`, fetcher, {
dedupingInterval: 300000,
dedupingInterval: 60000,
})
return {
blob: data,
isBlobLoading: isLoading,
isBlobError: error,
}
}

export function useRepoList() {
const { data, error, isLoading } = useSWR(`${relay}/relay/api/v1/repo_list`, fetcher, {
dedupingInterval: 30000,
})
return {
data: data,
isLoading,
isError: error,
}
}
10 changes: 0 additions & 10 deletions lunar/src/app/api/relay/repo_list/route.ts

This file was deleted.

50 changes: 31 additions & 19 deletions lunar/src/app/application-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ import {
CodeBracketSquareIcon,
ArchiveBoxArrowDownIcon,
} from '@heroicons/react/20/solid'
import { invoke } from '@tauri-apps/api'
import { usePathname } from 'next/navigation'
import { useState, useEffect } from 'react'
import { Badge } from 'antd/lib'

function AccountDropdownMenu({ anchor }: { anchor: 'top start' | 'bottom end' }) {
return (
Expand Down Expand Up @@ -79,32 +81,41 @@ export function ApplicationLayout({
children: React.ReactNode
}) {
let pathname = usePathname()
const [token, setToken] = useState("")

const [mega_status, setMegaStatus] = useState(false)
useEffect(() => {
if (typeof window !== 'undefined') {
setToken(localStorage.getItem("access_token") || "")
}
const fetchStatus = () => {
invoke('mega_service_status')
.then((status: boolean) => {
setMegaStatus(status);
console.log(`Service Status: ${status}`);
})
.catch((error) => {
console.error(`Failed to get service status: ${error}`);
});
};
fetchStatus();
// Set up interval to fetch status every 10 seconds
const interval = setInterval(fetchStatus, 10000);
// Clean up interval on unmount
return () => clearInterval(interval);
}, [])

// const { user, isLoading, isError } = useUser(token);
// if (isLoading) return <Skeleton />;

return (
<SidebarLayout
navbar={
<Navbar>
<NavbarSpacer />
{/* {
token &&
<NavbarSection>
<Dropdown>
<DropdownButton as={NavbarItem}>
<Avatar src={"" || user.avatar_url} />
</DropdownButton>
<AccountDropdownMenu anchor="bottom end" />
</Dropdown>
</NavbarSection>
} */}

<NavbarSection>
<Dropdown>
<DropdownButton as={NavbarItem}>
<Avatar src={"/images/megaLogo.png"} />
</DropdownButton>
<AccountDropdownMenu anchor="bottom end" />
</Dropdown>
</NavbarSection>

</Navbar>
}
sidebar={
Expand All @@ -113,7 +124,8 @@ export function ApplicationLayout({
<Dropdown>
<DropdownButton as={SidebarItem}>
<Avatar src="/images/megaLogo.png" />
<SidebarLabel>Mega</SidebarLabel>
<SidebarLabel>Mega Status:</SidebarLabel>
<Badge status={mega_status ? "success" : "default"} text={mega_status ? "On" : "Off"} />
<ChevronDownIcon />
</DropdownButton>
<DropdownMenu className="min-w-80 lg:min-w-64" anchor="bottom start">
Expand Down
2 changes: 1 addition & 1 deletion lunar/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default function HomePage() {
<Skeleton />
}
{
(!isTreeLoading && !isBlobLoading) &&
(tree && blob) &&
<CodeTable directory={tree.data} readmeContent={blob.data} treeIsShow={false} />
}
</Layout>
Expand Down
35 changes: 12 additions & 23 deletions lunar/src/app/repo/page.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
'use client'

import React, { useEffect, useState } from 'react'
import DataList from '@/components/DataList'
import { useRepoList } from '../api/fetcher';
import { Skeleton } from "antd";


export default function HomePage() {
const [repo_list, setRepoList] = useState([]);

useEffect(() => {
const fetchData = async () => {
try {
let repo_list = await getRepoList();
setRepoList(repo_list);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
}, []);
export default function RepoPage() {
const { data, isLoading, isError } = useRepoList();

return (
<div>
<DataList data={repo_list} />
{
isLoading &&
<Skeleton />
}
{
!isLoading &&
<DataList data={data} />
}
</div>
)
}

async function getRepoList() {
const res = await fetch(`api/relay/repo_list`);
const response = await res.json();
const repo_list = response.data;
return repo_list
}
Loading