feat: Implement default welcome page for missing web application

- Added a professional HTML welcome page displayed when no web application is configured.
- Enhanced `_load_webapp()` method to support improved path resolution for both development and bundled modes.
- Updated error handling to show the welcome page instead of a bare error message when the webapp file is not found.
- Modified unit tests to verify the welcome page is displayed in error scenarios.

build: Complete Windows and macOS build scripts

- Created `build_windows.py` for building Windows executable and optional MSI installer using PyInstaller.
- Developed `build_macos.sh` for creating macOS application bundle and DMG image.
- Added logging and error handling to build scripts for better user feedback.

docs: Add build and icon requirements documentation

- Created `PHASE_3_BUILD_SUMMARY.md` detailing the build process, results, and next steps.
- Added `resources/icons/README.md` outlining icon requirements and creation guidelines.

chore: Sync remotes script for repository maintenance

- Introduced `sync_remotes.ps1` PowerShell script to fetch updates from origin and upstream remotes.
This commit is contained in:
claudi 2026-01-28 12:59:33 +01:00
parent 90dc09eb4d
commit f0c96f15b8
10 changed files with 1415 additions and 39 deletions

View file

@ -11,6 +11,160 @@ from webdrop_bridge.core.drag_interceptor import DragInterceptor
from webdrop_bridge.core.validator import PathValidator
from webdrop_bridge.ui.restricted_web_view import RestrictedWebEngineView
# Default welcome page HTML when no webapp is configured
DEFAULT_WELCOME_PAGE = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebDrop Bridge</title>
<style>
* {{
margin: 0;
padding: 0;
box-sizing: border-box;
}}
body {{
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}}
.container {{
background: white;
border-radius: 12px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
padding: 60px 40px;
max-width: 600px;
text-align: center;
}}
h1 {{
color: #667eea;
font-size: 2.5em;
margin-bottom: 10px;
}}
.version {{
color: #999;
font-size: 0.9em;
margin-bottom: 30px;
}}
p {{
color: #555;
font-size: 1.1em;
line-height: 1.6;
margin-bottom: 20px;
}}
.features {{
background: #f5f5f5;
border-radius: 8px;
padding: 30px;
margin: 30px 0;
text-align: left;
}}
.features h2 {{
color: #333;
font-size: 1.2em;
margin-bottom: 15px;
text-align: center;
}}
.features ul {{
list-style: none;
padding: 0;
}}
.features li {{
color: #666;
padding: 10px 0;
border-bottom: 1px solid #ddd;
}}
.features li:last-child {{
border-bottom: none;
}}
.features li:before {{
content: "";
color: #667eea;
font-weight: bold;
margin-right: 10px;
}}
.status {{
background: #fff3cd;
border: 1px solid #ffc107;
border-radius: 6px;
padding: 15px;
margin: 20px 0;
color: #856404;
}}
.status strong {{
display: block;
margin-bottom: 5px;
}}
.footer {{
color: #999;
font-size: 0.9em;
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #eee;
}}
</style>
</head>
<body>
<div class="container">
<h1>🌉 WebDrop Bridge</h1>
<div class="version">Professional Web-to-File Drag-and-Drop Bridge</div>
<div class="status">
<strong> Application Ready</strong>
No web application is currently configured.
Configure WEBAPP_URL in your .env file to load your custom application.
</div>
<p>WebDrop Bridge is a professional desktop application that seamlessly converts web-based drag-and-drop interactions into native file operations on Windows and macOS.</p>
<div class="features">
<h2>Key Features</h2>
<ul>
<li>Drag-and-drop from web interface to desktop</li>
<li>Real-time drag state monitoring</li>
<li>Path validation and security controls</li>
<li>Cross-platform support (Windows & macOS)</li>
<li>Professional production-grade architecture</li>
<li>Comprehensive logging and monitoring</li>
</ul>
</div>
<p><strong>To configure your web application:</strong></p>
<ol style="text-align: left; color: #666; margin-top: 15px;">
<li>Create a <code>.env</code> file in your application directory</li>
<li>Set <code>WEBAPP_URL</code> to your HTML file path or HTTP URL</li>
<li>Example: <code>WEBAPP_URL=file:///./webapp/index.html</code></li>
<li>Restart the application</li>
</ol>
<div class="footer">
<strong>Version:</strong> {version}<br>
<strong>Status:</strong> Ready for configuration
</div>
</div>
</body>
</html>
"""
class MainWindow(QMainWindow):
"""Main application window for WebDrop Bridge.
@ -77,6 +231,8 @@ class MainWindow(QMainWindow):
"""Load the web application.
Loads HTML from the configured webapp URL or from local file.
Supports both bundled apps (PyInstaller) and development mode.
Falls back to default welcome page if webapp not found.
"""
webapp_url = self.config.webapp_url
@ -87,12 +243,26 @@ class MainWindow(QMainWindow):
# Local file path
try:
file_path = Path(webapp_url).resolve()
# If path doesn't exist, try relative to application root
# This handles both development and bundled (PyInstaller) modes
if not file_path.exists():
self.web_view.setHtml(
f"<html><body><h1>Error</h1>"
f"<p>Web application file not found: {file_path}</p>"
f"</body></html>"
)
# Try relative to application package root
app_root = Path(__file__).parent.parent.parent.parent
relative_path = app_root / webapp_url.lstrip("file:///").lstrip("./")
if relative_path.exists():
file_path = relative_path
else:
# Try without leading "./"
alt_path = Path(webapp_url.lstrip("file:///").lstrip("./")).resolve()
if alt_path.exists():
file_path = alt_path
if not file_path.exists():
# Show welcome page with instructions
welcome_html = DEFAULT_WELCOME_PAGE.format(version=self.config.app_version)
self.web_view.setHtml(welcome_html)
return
# Load local file as file:// URL
@ -100,11 +270,9 @@ class MainWindow(QMainWindow):
self.web_view.load(QUrl(file_url))
except (OSError, ValueError) as e:
self.web_view.setHtml(
f"<html><body><h1>Error</h1>"
f"<p>Failed to load web application: {e}</p>"
f"</body></html>"
)
# Show welcome page on error
welcome_html = DEFAULT_WELCOME_PAGE.format(version=self.config.app_version)
self.web_view.setHtml(welcome_html)
def _apply_stylesheet(self) -> None:
"""Apply application stylesheet if available."""