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
1 change: 0 additions & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,3 @@ network-interface = "2.0.5"
[target.'cfg(any(target_os = "macos", windows, target_os = "linux"))'.dependencies]
tauri-plugin-updater = "2"
tauri-plugin-process = "2"

24 changes: 12 additions & 12 deletions src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"opener:default",
"updater:default",
"process:default"
]
}
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"opener:default",
"updater:default",
"process:default"
]
}
3 changes: 3 additions & 0 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub struct AppSettings {
pub obs: OBSSettings,
pub master: MasterSettings,
pub slave: SlaveSettings,
#[serde(default)]
pub donation_dialog_shown: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -69,6 +71,7 @@ impl Default for AppSettings {
default_host: "192.168.1.100".to_string(),
default_port: 8080,
},
donation_dialog_shown: false,
}
}
}
Expand Down
57 changes: 57 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,58 @@ button:not(:disabled):active {
margin-top: auto;
}

.footer-content {
display: flex;
justify-content: center;
align-items: center;
gap: 2rem;
margin-bottom: 1rem;
flex-wrap: wrap;
}

.footer-copyright {
margin-top: 0.5rem;
}

.btn-donation {
background: linear-gradient(135deg, #a855f7 0%, #7c3aed 100%);
color: white;
padding: 0.625rem 1.25rem;
border-radius: 9999px;
font-size: 0.875rem;
font-weight: 600;
box-shadow: 0 4px 12px rgba(168, 85, 247, 0.3);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 1px solid rgba(255, 255, 255, 0.1);
position: relative;
overflow: hidden;
}

.btn-donation::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s;
}

.btn-donation:hover:not(:disabled)::before {
left: 100%;
}

.btn-donation:hover:not(:disabled) {
transform: translateY(-2px) scale(1.05);
box-shadow: 0 8px 20px rgba(168, 85, 247, 0.5);
background: linear-gradient(135deg, #9333ea 0%, #6b21a8 100%);
}

.btn-donation:active:not(:disabled) {
transform: translateY(0) scale(1.02);
}

/* Responsive */
@media (max-width: 768px) {
.app-header {
Expand Down Expand Up @@ -733,6 +785,11 @@ button:not(:disabled):active {
.mode-badge {
width: 100%;
}

.footer-content {
flex-direction: column;
gap: 1rem;
}
}

/* Toast Container Override */
Expand Down
44 changes: 41 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import { AlertPanel } from "./components/AlertPanel";
import { OBSSourceList } from "./components/OBSSourceList";
import { SplashScreen } from "./components/SplashScreen";
import { VersionInfo } from "./components/VersionInfo";
import { DonationModal } from "./components/DonationModal";
import { AppMode } from "./types/sync";

function App() {
const [showSplash, setShowSplash] = useState(true);
const [showDonationModal, setShowDonationModal] = useState(false);
const [appMode, setAppMode] = useState<AppMode | null>(null);
const [obsHost, setObsHost] = useState("localhost");
const [obsPort, setObsPort] = useState(4455);
Expand Down Expand Up @@ -128,11 +130,38 @@ function App() {
}
};

const handleSplashComplete = () => {
setShowSplash(false);
// Show donation modal if it hasn't been shown before
if (settings && !settings.donationDialogShown) {
setShowDonationModal(true);
}
};

const handleCloseDonationModal = async () => {
setShowDonationModal(false);
// Mark donation dialog as shown
if (settings) {
try {
await saveSettings({
...settings,
donationDialogShown: true,
});
} catch (error) {
console.error("Failed to save donation dialog status:", error);
}
}
};

return (
<div className="app">
{showSplash && (
<SplashScreen onComplete={() => setShowSplash(false)} />
<SplashScreen onComplete={handleSplashComplete} />
)}
<DonationModal
isOpen={showDonationModal}
onClose={handleCloseDonationModal}
/>
<ToastContainer
position="top-right"
autoClose={3000}
Expand Down Expand Up @@ -381,8 +410,17 @@ function App() {
</main>

<footer className="app-footer">
<VersionInfo />
<p>© 2026 OBS Sync - イベント向けOBS同期システム</p>
<div className="footer-content">
<VersionInfo />
<button
onClick={() => setShowDonationModal(true)}
className="btn-donation"
title="開発者をサポート"
>
💜 寄付する
</button>
</div>
<p className="footer-copyright">© 2026 OBS Sync - イベント向けOBS同期システム</p>
</footer>
</div>
);
Expand Down
156 changes: 156 additions & 0 deletions src/components/DonationModal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
.donation-modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.75);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
animation: fadeIn 0.2s ease-out;
}

@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

.donation-modal-content {
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
border-radius: 16px;
padding: 32px;
max-width: 500px;
width: 90%;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.1);
animation: slideUp 0.3s ease-out;
}

@keyframes slideUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}

.donation-modal-header {
text-align: center;
margin-bottom: 24px;
padding-bottom: 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.donation-modal-header h2 {
margin: 0 0 8px 0;
font-size: 28px;
color: #fff;
font-weight: 700;
}

.developer-name {
margin: 0;
font-size: 16px;
color: #a0a0a0;
font-weight: 500;
}

.donation-modal-body {
margin-bottom: 28px;
}

.donation-message {
font-size: 18px;
font-weight: 600;
color: #fff;
margin: 0 0 16px 0;
text-align: center;
}

.donation-description {
font-size: 15px;
color: #c0c0c0;
line-height: 1.6;
margin: 0;
text-align: center;
}

.donation-modal-actions {
display: flex;
flex-direction: column;
gap: 12px;
}

.btn-donate {
padding: 14px 28px;
font-size: 16px;
font-weight: 600;
background: linear-gradient(135deg, #9146ff 0%, #772ce8 100%);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}

.btn-donate:hover:not(:disabled) {
background: linear-gradient(135deg, #a55fff 0%, #8741ee 100%);
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(145, 70, 255, 0.4);
}

.btn-donate:active:not(:disabled) {
transform: translateY(0);
}

.btn-donate:disabled {
opacity: 0.6;
cursor: not-allowed;
}

.btn-close-modal {
padding: 12px 24px;
font-size: 15px;
font-weight: 500;
background: transparent;
color: #a0a0a0;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
}

.btn-close-modal:hover {
color: #fff;
border-color: rgba(255, 255, 255, 0.4);
background: rgba(255, 255, 255, 0.05);
}

.spinner {
display: inline-block;
width: 14px;
height: 14px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 0.6s linear infinite;
}

@keyframes spin {
to {
transform: rotate(360deg);
}
}
Loading