Skip to content
Open
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
266 changes: 154 additions & 112 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rise",
"version": "0.0.3",
"version": "0.0.4",
"description": "",
"type": "module",
"scripts": {
Expand All @@ -15,16 +15,18 @@
"dependencies": {
"@tauri-apps/api": "^2.9.0",
"@tauri-apps/plugin-dialog": "^2.4.2",
"cookie": "^1.1.1",
"lucide-svelte": "^0.525.0",
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0",
"xterm-addon-web-links": "^0.9.0"
},
"devDependencies": {
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.9.0",
"@sveltejs/kit": "^2.49.2",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tauri-apps/cli": "^2.9.2",
"@types/node": "^24.10.2",
"sass-embedded": "^1.89.2",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rise"
version = "0.0.3"
version = "0.0.4"
description = "RISE IDE build for success"
authors = ["you"]
edition = "2021"
Expand Down
75 changes: 74 additions & 1 deletion src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::collections::{HashMap, HashSet};
use std::sync::Mutex;
use streaming_iterator::StreamingIterator;
use crate::highlight::{escape_html, calculate_edit, highlight_ast};
use serde_json;

#[derive(Clone, Debug)]
struct EditEntry {
Expand All @@ -23,6 +24,72 @@ pub struct EditorBuffer {

lazy_static! {
pub static ref EDITOR_BUFFERS: Mutex<HashMap<String, EditorBuffer>> = Mutex::new(HashMap::new());
pub static ref CONFIG_FILE: String = Path::new("/Users/ddorabble/RISE").to_string_lossy().into_owned();
}

#[derive(Serialize, Deserialize, Debug, Clone)]
struct AppConfig {
recent_projects: Vec<String>,
theme: String,
}

impl Default for AppConfig {
fn default() -> Self {
AppConfig { recent_projects: Vec::new(), theme: "default".to_string() }
}
}

fn load_config() -> AppConfig {
let path = Path::new(&*CONFIG_FILE);
if !path.exists() {
// create with defaults
fs::create_dir(path).expect("Failed to create config directory");
let cfg = AppConfig::default();
let _ = save_config(&cfg);
return cfg;
}
let content = fs::read_to_string(path.join("config.json")).unwrap_or_else(|_| String::new());
if content.trim().is_empty() {
let cfg = AppConfig::default();
let _ = save_config(&cfg);
return cfg;
}
match serde_json::from_str::<AppConfig>(&content) {
Ok(mut cfg) => {
// Backfill defaults if fields are missing
if cfg.theme.is_empty() { cfg.theme = "default".to_string(); }
if cfg.recent_projects.len() > 10 { cfg.recent_projects.truncate(10); }
cfg
}
Err(_) => {
// If existing file is not valid JSON (from previous versions), reset to defaults
let cfg = AppConfig::default();
let _ = save_config(&cfg);
cfg
}
}
}

fn save_config(cfg: &AppConfig) -> Result<(), String> {
let json = serde_json::to_string_pretty(cfg).map_err(|e| format!("Failed to serialize config: {}", e))?;
fs::write(Path::new(&*CONFIG_FILE).join("config.json"), json).map_err(|e| format!("Failed to write config file: {}", e))
}

fn update_recent_project(project_path: &str) -> Result<(), String> {
let mut cfg = load_config();
// remove existing occurrences
cfg.recent_projects.retain(|p| p != project_path);
// insert at front
cfg.recent_projects.insert(0, project_path.to_string());
// cap at 10
if cfg.recent_projects.len() > 10 { cfg.recent_projects.truncate(10); }
save_config(&cfg)
}

#[tauri::command]
pub fn get_recent_projects() -> Result<Vec<String>, String> {
let cfg = load_config();
Ok(cfg.recent_projects)
}

#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -67,6 +134,8 @@ pub async fn create_project(path: Option<String>, project_name: Option<String>)
let readme_path = project_path.join("README.md");
let readme_content = format!("# {} Project\n\nThis project was created with RISE.\n", folder_name);
fs::write(&readme_path, readme_content).map_err(|e| format!("Failed to create README.md file: {}", e))?;
// Ensure config exists and update recent projects list
update_recent_project(project_path.to_str().unwrap_or_default())?;
project_path.to_str().map(|s| s.to_string()).ok_or_else(|| "Failed to convert project path to string".to_string())
},
None => Err("No path provided".to_string())
Expand All @@ -76,7 +145,11 @@ pub async fn create_project(path: Option<String>, project_name: Option<String>)
#[tauri::command]
pub async fn open_project(path: Option<String>) -> Result<String, String> {
match path {
Some(p) => Ok(p),
Some(p) => {
// Ensure config exists and update the recent projects list
update_recent_project(&p)?;
Ok(p)
},
None => Err("No path provided".to_string())
}
}
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use cocoa::appkit::{NSWindowStyleMask, NSWindowTitleVisibility};
use cocoa::base::YES;

pub use commands::{
get_recent_projects,
create_project,
execute_command,
execute_command_with_shell,
Expand Down Expand Up @@ -39,6 +40,7 @@ pub fn run() {
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_fs::init())
.invoke_handler(tauri::generate_handler![
get_recent_projects,
open_project,
create_project,
read_file,
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"productName": "RISE",
"mainBinaryName": "RISE",
"version": "0.0.3",
"version": "0.0.4",
"identifier": "com.rise.app",
"plugins": {},
"app": {
Expand Down
9 changes: 7 additions & 2 deletions src/lib/stores/fileStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { writable } from 'svelte/store';
import type { FileEntry } from '$lib/utils/types';
import { invoke } from '@tauri-apps/api/core';
import { basename, dirname } from '@tauri-apps/api/path';

// Initialize the store with default values
export const fileStore = writable<{
Expand All @@ -16,7 +17,7 @@ export const fileStore = writable<{
function makeRoot(projectPath: string, children: FileEntry[] = []): FileEntry {
return {
path: projectPath,
name: projectPath.split('/').pop() || projectPath,
name: projectPath,
is_dir: true,
expanded: true,
children,
Expand Down Expand Up @@ -77,7 +78,11 @@ export async function refreshPathInStore(path: string) {
let dirPath = path;
const targetNode = findNode(tree, path);
if (targetNode && !targetNode.is_dir) {
dirPath = path.split('/').slice(0, -1).join('/') || currentProjectPath;
try {
dirPath = await dirname(path);
} catch {
dirPath = currentProjectPath as string;
}
}

// For project root, ensure we reload children directly under root
Expand Down
4 changes: 3 additions & 1 deletion src/lib/utils/fileLoader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { invoke } from "@tauri-apps/api/core";
import type { FileEntry } from "./types";
import { basename, dirname } from "@tauri-apps/api/path";

// Pure helper to load directory contents and normalize fields without holding module state
export async function loadFiles(path: string, level: number = 0): Promise<FileEntry[]> {
Expand All @@ -8,7 +9,8 @@ export async function loadFiles(path: string, level: number = 0): Promise<FileEn

for (const file of dirFiles) {
file.level = level;
file.parent_dir = path.split("/").slice(-2, -1)[0] || "";
const parent = await dirname(path);
file.parent_dir = await basename(parent) || "";
if (file.is_dir) {
file.expanded = false;
file.children = [];
Expand Down
15 changes: 14 additions & 1 deletion src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
<script lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { open } from "@tauri-apps/plugin-dialog"
import {onMount} from "svelte";

let showProjectNameDialog = false;
let projectName = "rise-project";
let selectedBasePath = "";
let projectNameInput: HTMLInputElement;
let sanitizedName = "";
let showSanitizeWarning = false;
let recentProjects: string[] = [];

async function loadRecentProjects() {
recentProjects = await invoke("get_recent_projects");
console.log(recentProjects);
}

onMount(loadRecentProjects);

async function openProject(event: Event) {
event.preventDefault();
Expand Down Expand Up @@ -109,12 +118,16 @@
<li><button class="bt bt--open" onclick={openProject}>Open Project <br>🗂️</button></li>
</ul>
</div>
{#if recentProjects.length > 0}
<div>
<h2>Recent Projects</h2>
<ul class="buttons">
<!-- TODO: create cycle to go through recent projects -->
{#each recentProjects as recentProject}
<li><button class="bt bt--recent" onclick={() => window.location.href = `/editor?path=${recentProject}`}>{recentProject}</button></li>
{/each}
</ul>
</div>
{/if}
</div>

{#if showProjectNameDialog}
Expand Down
14 changes: 8 additions & 6 deletions src/routes/editor/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,18 @@
PlaySquare,
Settings
} from "lucide-svelte";
import { basename } from "@tauri-apps/api/path";

const SETTINGS: string[] = [
"Theme",
"Keymap",
"View Mode"
];

const PROJECTS: string[] = [
"DDD",
"LOL"
]
let PROJECTS: string[] = []

let projectPath: string | null = null;
let projectName: string | null = null;
let currentPath: string | null = null;
let files: FileEntry[] = [];
let allFiles: FileEntry[] = [];
Expand Down Expand Up @@ -110,9 +109,10 @@
projectPath = localStorage.getItem('projectPath');
if (projectPath) {
currentPath = projectPath;
projectName = await basename(projectPath);
const rootEntry: FileEntry = {
path: projectPath,
name: `${projectPath.split('/').pop()}`,
name: projectName || projectPath,
is_dir: true,
expanded: true,
children: [],
Expand Down Expand Up @@ -140,6 +140,8 @@
host = info.host;
home = info.home;

PROJECTS = await invoke('get_recent_projects');

// Editor component now handles keydown/focus; keep click/keyup here only for FileMenu interactions
window.addEventListener('keyup', handleInputEvent);
window.addEventListener('click', handleInputEvent);
Expand Down Expand Up @@ -258,7 +260,7 @@
y = 30;
actions = PROJECTS;
}}>
{projectPath ? projectPath.split('/').pop() : 'Untitled'}
{projectName ?? 'Untitled'}
<ChevronDown class="chevron-down" size={20} />
</button>
<div class="window-title--group">
Expand Down
11 changes: 8 additions & 3 deletions src/routes/editor/components/FileMenu.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { invoke } from "@tauri-apps/api/core";
import { join, dirname } from "@tauri-apps/api/path";
import {refreshPathInStore} from "$lib/stores/fileStore";
import Menu from "./Menu.svelte";

Expand Down Expand Up @@ -44,7 +45,7 @@

let onNameCreateConfirmed = async (name: string) => {
try {
const newPath = `${parentPath}/${name}`;
const newPath = await join(parentPath, name);
await invoke("perform_action", {
action,
file: { path: newPath, name, is_dir: isDirAction },
Expand All @@ -65,14 +66,18 @@
const parentPath = currentPath || projectPath;
let onNameRenameConfirmed = async (name: string) => {
try {
const newPath = parentPath.split("/").slice(0, -1).join('/').concat(`/${name}`);
const parentDir = await dirname(parentPath);
const newPath = await join(parentDir, name);
console.log("New path:", newPath, " Parent path:", parentPath, " Name:", name);
await invoke("perform_action", {
action,
file: { path: parentPath, name, is_dir: isDirAction },
newName: newPath
});
await refreshPathInStore(parentPath);
const oldParent = await dirname(parentPath);
const newParent = await dirname(newPath);
await refreshPathInStore(oldParent);
await refreshPathInStore(newParent);
} catch (e) {
console.error("Failed to create item:", e);
throw e;
Expand Down
Loading