remotedroid-control-hub / nodeview.html
m384's picture
das is nicht was ich meinte, ein richtiger workspace, kariert im hintergrund und das display wird auch dort angezeigt nicht nur ein kleiner runder icon das bringt mir so nix
f0567ac verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RemoteDroid - Node View</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<style>
body {
background-color: #111;
background-image:
linear-gradient(#333 1px, transparent 1px),
linear-gradient(90deg, #333 1px, transparent 1px);
background-size: 40px 40px;
}
.device-frame {
background: #222;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
overflow: hidden;
position: relative;
}
.device-screen {
background: #000;
width: 100%;
height: 100%;
overflow: hidden;
}
.node-container {
background: rgba(30, 30, 30, 0.9);
border: 1px solid #444;
transition: all 0.3s ease;
}
.connection-line {
stroke: #6366f1;
stroke-width: 2;
opacity: 0.6;
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<div class="container mx-auto px-4 py-8">
<header class="flex justify-between items-center mb-8">
<div>
<h1 class="text-4xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-purple-400 to-pink-600">
Node View
</h1>
<p class="text-gray-300">Visualize connected device network</p>
</div>
<div class="flex items-center space-x-4">
<a href="index.html" class="bg-purple-600 hover:bg-purple-700 px-6 py-2 rounded-full flex items-center">
<i data-feather="arrow-left" class="mr-2"></i> Back to Control Hub
</a>
</div>
</header>
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
<!-- Sidebar -->
<div class="lg:col-span-1">
<div class="bg-gray-800 bg-opacity-50 backdrop-blur-md rounded-xl p-6 mb-6">
<h2 class="text-lg font-semibold mb-4 flex items-center">
<i data-feather="cpu" class="mr-2"></i> Active Devices
</h2>
<div class="space-y-3" id="device-list">
<!-- Device list will be populated by JavaScript -->
</div>
</div>
<div class="bg-gray-800 bg-opacity-50 backdrop-blur-md rounded-xl p-6">
<h2 class="text-lg font-semibold mb-4 flex items-center">
<i data-feather="settings" class="mr-2"></i> Controls
</h2>
<div class="space-y-4">
<button id="add-device" class="w-full bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-md flex items-center justify-center">
<i data-feather="plus" class="mr-2"></i> Add Simulated Device
</button>
<button id="refresh-network" class="w-full bg-gray-700 hover:bg-gray-600 px-4 py-2 rounded-md flex items-center justify-center">
<i data-feather="refresh-cw" class="mr-2"></i> Refresh
</button>
</div>
</div>
</div>
<!-- Main Visualization -->
<div class="lg:col-span-3">
<div class="rounded-xl p-6 h-full">
<h2 class="text-lg font-semibold mb-4">Device Workspace</h2>
<div id="node-visualization" class="w-full h-96 lg:h-auto" style="min-height: 500px;">
<svg class="w-full h-full" id="network-svg"></svg>
</div>
</div>
</div>
</div>
<!-- Device Details Modal -->
<div id="device-modal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden">
<div class="flex items-center justify-center h-full">
<div class="bg-gray-800 rounded-xl p-6 max-w-md w-full mx-4">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold">Device Details</h3>
<button id="close-modal" class="text-gray-400 hover:text-white">
<i data-feather="x"></i>
</button>
</div>
<div id="device-details" class="space-y-3">
<!-- Details will be populated by JavaScript -->
</div>
</div>
</div>
</div>
</div>
<script>
// Initial devices data
let devices = [
{ id: 1, name: "Pixel 6", ip: "192.168.1.101", status: "active", battery: 87, type: "android", lastSync: "2 min ago" },
{ id: 2, name: "Galaxy S22", ip: "192.168.1.102", status: "active", battery: 64, type: "android", lastSync: "1 min ago" },
{ id: 3, name: "iPhone 14", ip: "192.168.1.103", status: "idle", battery: 92, type: "ios", lastSync: "5 min ago" },
{ id: 4, name: "Xperia 5", ip: "192.168.1.104", status: "active", battery: 53, type: "android", lastSync: "3 min ago" }
];
// D3.js Network Visualization
const width = document.getElementById('network-svg').clientWidth;
const height = document.getElementById('network-svg').clientHeight || 500;
const svg = d3.select('#network-svg')
.attr('viewBox', `0 0 ${width} ${height}`);
// Create force simulation
const simulation = d3.forceSimulation()
.force('link', d3.forceLink().id(d => d.id).distance(250))
.force('charge', d3.forceManyBody().strength(-200))
.force('center', d3.forceCenter(width / 2, height / 2))
.force('collision', d3.forceCollide().radius(d => d.type === 'hub' ? 100 : 80));
// Initialize network
function initNetwork() {
// Clear existing
svg.selectAll('*').remove();
const nodes = devices.map(d => ({ ...d }));
const links = [];
// Create links between devices and central hub
devices.forEach(d => {
links.push({ source: 'hub', target: d.id });
});
nodes.push({ id: 'hub', name: 'Control Hub', type: 'hub' });
// Create container
const g = svg.append('g');
// Create links
const link = g.append('g')
.selectAll('line')
.data(links)
.enter().append('line')
.attr('class', 'connection-line');
// Create nodes
const node = g.append('g')
.selectAll('g')
.data(nodes)
.enter().append('g')
.attr('class', 'node-container')
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
// Add device frames
node.append('foreignObject')
.attr('width', 160)
.attr('height', 300)
.attr('x', -80)
.attr('y', -150)
.append('xhtml:div')
.attr('class', 'device-frame')
.style('width', '160px')
.style('height', '300px')
.html(d => {
if (d.type === 'hub') return `<div class="device-screen flex items-center justify-center text-white">Control Hub</div>`;
return `
<div class="device-screen">
<img src="http://static.photos/technology/160x300/${d.id}" class="w-full h-full object-cover" alt="Device screen">
</div>
`;
})
.on('click', (event, d) => showDeviceDetails(d));
// Add device labels
node.append('text')
.attr('dy', 170)
.attr('text-anchor', 'middle')
.attr('fill', '#e5e7eb')
.style('font-size', '12px')
.text(d => d.name || d.id);
simulation.nodes(nodes);
simulation.force('link').links(links);
simulation.on('tick', () => {
link
.attr('x1', d => d.source.x)
.attr('y1', d => d.source.y)
.attr('x2', d => d.target.x)
.attr('y2', d => d.target.y);
node
.attr('transform', d => `translate(${d.x},${d.y})`);
});
}
// Drag functions
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}
// Functions for UI interactions
function renderDeviceList() {
const deviceList = document.getElementById('device-list');
deviceList.innerHTML = '';
devices.forEach(device => {
const div = document.createElement('div');
div.className = 'flex items-center justify-between p-2 rounded hover:bg-gray-700 cursor-pointer';
div.innerHTML = `
<div class="flex items-center">
<span class="mr-2">${device.type === 'ios' ? '🍎' : 'πŸ€–'}</span>
<span class="text-sm">${device.name}</span>
</div>
<div class="w-3 h-3 rounded-full ${device.status === 'active' ? 'bg-green-500' : 'bg-gray-500'}"></div>
`;
deviceList.appendChild(div);
});
}
function showDeviceDetails(device) {
if (device.id === 'hub') return;
const modal = document.getElementById('device-modal');
const details = document.getElementById('device-details');
details.innerHTML = `
<div>
<span class="text-gray-400">Name:</span>
<span>${device.name}</span>
</div>
<div>
<span class="text-gray-400">IP Address:</span>
<span>${device.ip}</span>
</div>
<div>
<span class="text-gray-400">Battery:</span>
<span>${device.battery}%</span>
</div>
<div>
<span class="text-gray-400">Status:</span>
<span class="${device.status === 'active' ? 'text-green-400' : 'text-gray-400'}">${device.status}</span>
</div>
<div>
<span class="text-gray-400">Last Sync:</span>
<span>${device.lastSync}</span>
</div>
<button class="w-full bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-md mt-4">
Connect to this device
</button>
`;
modal.classList.remove('hidden');
}
// Event listeners
document.getElementById('add-device').addEventListener('click', () => {
const newDevice = {
id: devices.length + 1,
name: `Device ${devices.length + 1}`,
ip: `192.168.1.${100 + devices.length + 1}`,
status: 'active',
battery: Math.floor(Math.random() * 100),
type: Math.random() > 0.3 ? 'android' : 'ios',
lastSync: 'Just now'
};
devices.push(newDevice);
renderDeviceList();
initNetwork();
});
document.getElementById('refresh-network').addEventListener('click', () => {
initNetwork();
});
document.getElementById('close-modal').addEventListener('click', () => {
document.getElementById('device-modal').classList.add('hidden');
});
// Initialize
renderDeviceList();
initNetwork();
feather.replace();
</script>
</body>
</html>