add first launch info

This commit is contained in:
rambros 2026-03-19 16:43:05 +05:30
parent ad73ce0571
commit 6918c5e2a5
3 changed files with 103 additions and 27 deletions

View file

@ -20,7 +20,7 @@ a = Analysis(
['disco-reaper.py'],
pathex=[],
binaries=[],
datas=[],
datas=[('src/first-info.md', 'src')],
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},

24
src/first-info.md Normal file
View file

@ -0,0 +1,24 @@
# Welcome to the Reaper
> **The goal isn't just to leave Discord - it's to build a future where online communities don't require surrendering your biometric data and identity documents to participate. [Learn More](https://github.com/DukePantarei/discord-alternatives-wishlist/blob/main/BACKGROUND.md)**
Reaper tool solely exists to preserve your Server's message history and help you migrate to better platforms which actually respect you.
---
### Important Note
- The **migrated messages cannot be edited or deleted** by the original sender.
- So make sure to **get permission from fellow members** if you're using this tool on **private servers**
---
### Join our Community
- Join the **Reaper Community** if you need any help.
- Provide your suggestions / request new features.
- Invite link: https://fluxer.gg/2jlTwB0w
`This tool was developed independently. Not affiliated with or endorsed by Fluxer, Stoat or Discord.`

View file

@ -6,10 +6,10 @@ from pathlib import Path
logger = logging.getLogger(__name__)
from textual.app import App, ComposeResult
from textual.containers import Container, Horizontal, Vertical, VerticalScroll
from textual.containers import Container, Horizontal, Vertical, VerticalScroll, Center
from textual.widgets import (
Header, Footer, Button, Label, Input, ListItem,
ListView, Rule, RadioButton, RadioSet, Select, Static,
ListView, Rule, RadioButton, RadioSet, Select, Static, Markdown
)
from textual.screen import Screen, ModalScreen
@ -21,9 +21,46 @@ from src.core.utils import get_app_version
# ──────────────────────────────────────────────────────────────────────────────
# Modal: create a new ReaperFiles-* config folder
# Modals
# ──────────────────────────────────────────────────────────────────────────────
class FirstInfoModal(ModalScreen[str]):
"""Modal to display first-time launch info."""
DEFAULT_CSS = """
FirstInfoModal { align: center middle; }
#first_info_dialog {
width: 80%; height: auto; max-height: 80%;
border: thick $background 80%; background: $surface; padding: 1 2;
}
#btn_yeah { width: 100%; margin-top: 1; }
"""
def compose(self) -> ComposeResult:
with VerticalScroll(id="first_info_dialog"):
try:
import sys
import os
# Handle PyInstaller path resolution
if getattr(sys, 'frozen', False):
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
file_path = os.path.join(base_path, "src", "first-info.md")
with open(file_path, "r", encoding="utf-8") as f:
md_text = f.read()
except Exception as e:
md_text = f"# Welcome to the Reaper\n\nInfo text missing. ({e})"
yield Markdown(md_text)
yield Button("Get Started", variant="success", id="btn_yeah")
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "btn_yeah":
self.dismiss("start_new")
class NewConfigModal(ModalScreen[str]):
"""Modal to enter a name for a new configuration."""
@ -90,10 +127,12 @@ class ConfigSelectionScreen(Screen):
}
#config_sel_actions { height: auto; margin-top: 0; }
#config_sel_actions Button { width: 1fr; margin: 0 1; }
#btn_about { margin-top: 2; border: none; }
"""
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
with Center():
with Container(id="config_sel_container"):
yield Label(f"{get_app_version()} — Select Configuration", id="config_sel_title")
with VerticalScroll(id="config_list_container"):
@ -101,22 +140,30 @@ class ConfigSelectionScreen(Screen):
with Horizontal(id="config_sel_actions"):
yield Button("New Config", id="btn_new_config", variant="success", tooltip="Create a new configuration folder")
yield Button("Exit", id="btn_exit", variant="error")
with Center():
yield Button("Info", id="btn_about", tooltip="Show app information")
yield Footer()
yield Footnote()
yield RamDisplay()
def on_mount(self) -> None:
self.refresh_configs()
configs = self.refresh_configs()
if not configs:
def on_first_info_dismiss(res):
if res == "start_new":
self.action_new_config()
self.app.push_screen(FirstInfoModal(), on_first_info_dismiss)
def on_screen_resume(self) -> None:
self.refresh_configs()
def refresh_configs(self) -> None:
def refresh_configs(self) -> list:
configs = get_available_configs()
lv = self.query_one("#config_list", ListView)
lv.clear()
for c in configs:
lv.append(ListItem(Label(c), name=c))
return configs
def on_list_view_selected(self, event: ListView.Selected) -> None:
cfg_name = event.item.name
@ -124,8 +171,7 @@ class ConfigSelectionScreen(Screen):
from src.ui.mode_screen import ModeScreen
self.app.push_screen(ModeScreen(cfg_name, cfg_path))
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "btn_new_config":
def action_new_config(self) -> None:
def cb(name: str | None):
if name:
create_new_config(name)
@ -140,6 +186,12 @@ class ConfigSelectionScreen(Screen):
self.app.push_screen(ModeScreen(name, cfg_path))
self.app.push_screen(ConfigScreen(name, cfg_path), on_config_saved)
self.app.push_screen(NewConfigModal(), cb)
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "btn_new_config":
self.action_new_config()
elif event.button.id == "btn_about":
self.app.push_screen(FirstInfoModal())
elif event.button.id == "btn_exit":
self.app.exit()