AstraOS's picture
Update app.js
5826cb9 verified
class SakuraCyberDashboard {
constructor() {
this.consoleOutput = document.getElementById('console-output');
this.themeToggle = document.getElementById('theme-toggle');
this.currentTheme = 'sakura'; // Default theme
this.loadTheme();
this.themeToggle.addEventListener('click', () => this.toggleTheme());
}
log(message) {
const timestamp = new Date().toLocaleTimeString();
this.consoleOutput.innerHTML += `[${timestamp}] ${this.glitchText(message)}\n`;
this.consoleOutput.scrollTop = this.consoleOutput.scrollHeight;
}
glitchText(text) {
// Japanese-inspired glitch effect
const glitchChars = ['・', '◆', '◇', '■', '□'];
return text.split('').map(char =>
Math.random() > 0.9 ? glitchChars[Math.floor(Math.random() * glitchChars.length)] : char
).join('');
}
async launchVirtualBrowser() {
this.log('Initializing Virtual Browser...');
try {
// Check if user is signed in
const token = localStorage.getItem('authToken');
if (!token) {
// If not signed in, show sign in modal
this.showSignInModal();
return;
}
// User is signed in, open virtual browser in new window
const width = Math.min(1200, window.innerWidth * 0.9);
const height = width * (9/16); // 16:9 aspect ratio
const left = (window.innerWidth - width) / 2;
const top = (window.innerHeight - height) / 2;
window.open('vbrowser.html', 'Virtual Browser',
`width=${width},height=${height},left=${left},top=${top}`);
} catch (error) {
this.log(`Browser Launch Error: ${error.message}`);
}
}
async launchLiveStreamer() {
this.log('Connecting to Live Stream...');
try {
// Open the Telegram bot link in a new window
const width = Math.min(1000, window.innerWidth * 0.8);
const height = width * (9 / 16); // 16:9 aspect ratio
const left = (window.innerWidth - width) / 2;
const top = (window.innerHeight - height) / 2;
window.open(
'https://telegram.me/python3463_bot',
'Live Streamer',
`width=${width},height=${height},left=${left},top=${top}`
);
} catch (error) {
this.log(`Stream Connection Error: ${error.message}`);
}
}
async launchLiveLogs() {
this.log('Starting Log Trace Algorithm...');
try {
const width = Math.min(1000, window.innerWidth * 0.8);
const height = width * (9 / 16); // 16:9 aspect ratio
const left = (window.innerWidth - width) / 2;
const top = (window.innerHeight - height) / 2;
window.open(
'https://akshay-365.github.io/',
'Code Hacks',
`width=${width},height=${height},left=${left},top=${top}`);
} catch (error) {
this.log(`Trace Protocol Failure: ${error.message}`);
}
}
toggleTheme() {
this.currentTheme = this.currentTheme === 'sakura' ? 'program' : 'sakura';
this.applyTheme();
localStorage.setItem('theme', this.currentTheme);
}
loadTheme() {
const storedTheme = localStorage.getItem('theme');
if (storedTheme) {
this.currentTheme = storedTheme;
}
this.applyTheme();
}
applyTheme() {
const body = document.body;
const root = document.documentElement;
if (this.currentTheme === 'sakura') {
// Sakura Theme
root.style.setProperty('--background-primary', 'rgba(255, 255, 255, 0.1)');
root.style.setProperty('--background-secondary', 'rgba(255, 255, 255, 0.05)');
root.style.setProperty('--text-primary', '#f0f0f0');
root.style.setProperty('--text-secondary', '#c0c0c0');
root.style.setProperty('--accent-color', '#ff6b6b');
root.style.setProperty('--border-color', 'rgba(255, 255, 255, 0.2)');
body.style.background = 'linear-gradient(135deg, #1a1a2e, #16213e)';
this.themeToggle.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="theme-icon"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>';
// Update card icons
this.updateCardIcons('sakura');
} else if (this.currentTheme === 'program') {
// Program Theme
root.style.setProperty('--background-primary', 'rgba(255, 255, 255, 0.2)');
root.style.setProperty('--background-secondary', 'rgba(255, 255, 255, 0.2)');
root.style.setProperty('--text-primary', '#fff');
root.style.setProperty('--text-secondary', '#fff');
root.style.setProperty('--accent-color', '#5D3FD3');
root.style.setProperty('--border-color', 'rgba(255, 255, 255, 0.3)');
body.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
this.themeToggle.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="theme-icon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>';
// Update card icons
this.updateCardIcons('program');
}
}
updateCardIcons(theme) {
const virtualBrowserIcon = document.querySelector('.virtual-browser-card .card-icon');
const liveStreamerIcon = document.querySelector('.live-streamer-card .card-icon');
const liveLogsIcon = document.querySelector('.live-logs-card .card-icon');
if (theme === 'sakura') {
virtualBrowserIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon">
<path d="M4 8h16M4 16h16M3 12h18"></path>
</svg>`;
liveStreamerIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon">
<path d="M23 7l-7 5 7 5V7z"></path>
<rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect>
</svg>`;
liveLogsIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon">
<path d="M16 18l6-6-6-6"></path>
<path d="M2 12h20"></path>
</svg>`;
} else if (theme === 'program') {
virtualBrowserIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon">
<path d="M4 8h16M4 16h16M3 12h18"></path>
</svg>`;
liveStreamerIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon">
<path d="M23 7l-7 5 7 5V7z"></path>
<rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect>
</svg>`;
liveLogsIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon">
<path d="M16 18l6-6-6-6"></path>
<path d="M2 12h20"></path>
</svg>`;
}
}
showSignInModal() {
const modal = document.createElement('div');
modal.innerHTML = `
<div id="signInModal" style="
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
">
<div style="
background: var(--background-primary);
padding: 2rem;
border-radius: 15px;
border: 1px solid var(--border-color);
width: 90%;
max-width: 400px;
">
<h2 style="margin-bottom: 1rem; color: var(--text-primary)">Sign In</h2>
<input type="email" id="email" placeholder="Email" style="
width: 100%;
padding: 0.5rem;
margin-bottom: 1rem;
border: 1px solid var(--border-color);
background: var(--background-secondary);
color: var(--text-primary);
border-radius: 5px;
">
<input type="password" id="password" placeholder="Password" style="
width: 100%;
padding: 0.5rem;
margin-bottom: 1rem;
border: 1px solid var(--border-color);
background: var(--background-secondary);
color: var(--text-primary);
border-radius: 5px;
">
<div style="display: flex; justify-content: space-between;">
<button id="signInBtn" class="glass-btn">Sign In</button>
<button id="signUpBtn" class="glass-btn">Sign Up</button>
</div>
<button id="closeModal" style="
position: absolute;
top: 1rem;
right: 1rem;
background: none;
border: none;
color: var(--text-primary);
cursor: pointer;
font-size: 1.5rem;
">×</button>
</div>
</div>
`;
document.body.appendChild(modal);
const closeModal = () => {
document.body.removeChild(modal);
};
document.getElementById('closeModal').onclick = closeModal;
document.getElementById('signInBtn').onclick = async () => {
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
try {
const response = await fetch('/signin', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({email, password})
});
const data = await response.json();
if (data.token) {
localStorage.setItem('authToken', data.token);
closeModal();
this.launchVirtualBrowser();
} else {
alert(data.error || 'Sign in failed');
}
} catch (error) {
alert('Sign in failed: ' + error.message);
}
};
document.getElementById('signUpBtn').onclick = async () => {
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
try {
const response = await fetch('/signup', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({email, password})
});
const data = await response.json();
if (response.ok) {
alert('Account created! Please sign in.');
} else {
alert(data.error || 'Sign up failed');
}
} catch (error) {
alert('Sign up failed: ' + error.message);
}
};
}
}
// Initialize the dashboard
const dashboard = new SakuraCyberDashboard();
// Attach global window functions
window.launchVirtualBrowser = () => dashboard.launchVirtualBrowser();
window.launchLiveStreamer = () => dashboard.launchLiveStreamer();
window.launchLiveLogs = () => dashboard.launchLiveLogs();