This commit is contained in:
2025-11-12 23:39:48 +01:00
parent 9889acfe7b
commit b973d5ae36
16 changed files with 260 additions and 5 deletions

View File

@@ -11,7 +11,8 @@ files {
'html/index.html',
'html/style.css',
'html/app.js',
'html/img/apps/*'
'html/img/apps/*',
'html/img/wallpapers/*'
}
client_script 'client.lua'

View File

@@ -0,0 +1,75 @@
let dragging = false
let offsetX = 0;
let offsetY = 0;
const closeBtn = document.getElementById('closeBtn');
const phone = document.getElementById('phone');
const topbar = document.getElementById('topbar');
phone.classList.add('absolute', 'top-20', 'left-20');
topbar.classList.add('cursor-grab');
topbar.addEventListener('mousedown', e => {
if (e.target.closest('button') || e.target.closest('span')) return;
dragging = true;
topbar.classList.add('cursor-grabbing');
topbar.classList.remove('cursor-grab');
const rect = phone.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
});
window.addEventListener('mousemove', e => {
if (!dragging) return;
phone.style.left = `${e.clientX - offsetX}px`;
phone.style.top = `${e.clientY - offsetY}px`;
});
window.addEventListener('mouseup', () => {
if (!dragging) return;
dragging = false;
topbar.classList.remove('cursor-grabbing');
topbar.classList.add('cursor-grab');
});
window.addEventListener('message', function(event) {
const d = event.data;
if (!d) return;
if (d.action === 'toggle') {
if (d.open) {
phone.classList.remove('hidden');
updateTime();
} else {
phone.classList.add('hidden');
}
}
});
closeBtn?.addEventListener('click', () => {
phone.classList.add('hidden');
const parentResource = getParentResourceName();
fetch(`https://${parentResource}/close`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
});
function updateTime() {
const t = document.getElementById('time');
const now = new Date();
const hh = String(now.getHours()).padStart(2, '0');
const mm = String(now.getMinutes()).padStart(2, '0');
t.innerText = hh + ':' + mm;
}
function getParentResourceName() {
try {
return new URL(document.location).searchParams.get('parent') || window.parentResource || 'gb-phone';
} catch {
return 'gb-phone';
}
}

BIN
html/img/apps/browser.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
html/img/apps/camera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

BIN
html/img/apps/mail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
html/img/apps/music.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
html/img/apps/phone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
html/img/apps/photos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
html/img/apps/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -3,11 +3,82 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Phone</title>
<link rel="stylesheet" href="style.css">
<title>Phone UI</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
<!-- Phone Container -->
<div id="phone" class="~hidden w-72 h-[600px] rounded-3xl shadow-lg flex flex-col overflow-hidden">
<!-- Top Bar -->
<div id="topbar" class="h-12 bg-gray-200 flex items-center justify-between px-4 relative z-20">
<span id="time" class="text-xs text-gray-700">9:41</span>
<div class="flex space-x-1">
<span class="w-3 h-3 bg-gray-700 rounded-full"></span>
<span class="w-3 h-3 bg-gray-700 rounded-full"></span>
<span class="w-3 h-3 bg-gray-700 rounded-full"></span>
</div>
<button class="app flex flex-col items-center justify-center bg-gray-100/70 rounded-xl p-2 hover:bg-blue-100/80 transition transform hover:scale-105">
&times;
</button>
</div>
<!-- Wallpaper -->
<div id="wallpaper" class="absolute inset-0 bg-cover bg-center"></div>
<!-- Homescreen App Grid -->
<div class="flex-1 p-3 overflow-y-auto relative z-10">
<div class="grid grid-cols-4 gap-3">
<button class="app text-white flex flex-col items-center justify-center rounded-xl p-2 hover:bg-blue-100 transition transform hover:scale-105">
<img src="img/apps/messages.png" alt="Messages" class="w-10 h-10 mb-1"/>
<span class="text-xs">Messages</span>
</button>
<button class="app text-white flex flex-col items-center justify-center rounded-xl p-2 hover:bg-green-100 transition transform hover:scale-105">
<img src="img/apps/camera.png" alt="Camera" class="w-10 h-10 mb-1"/>
<span class="text-xs">Camera</span>
</button>
<button class="app text-white flex flex-col items-center justify-center rounded-xl p-2 hover:bg-yellow-100 transition transform hover:scale-105">
<img src="img/apps/photos.png" alt="Photos" class="w-10 h-10 mb-1"/>
<span class="text-xs">Photos</span>
</button>
<button class="app text-white flex flex-col items-center justify-center rounded-xl p-2 hover:bg-purple-100 transition transform hover:scale-105">
<img src="img/apps/settings.png" alt="Settings" class="w-10 h-10 mb-1"/>
<span class="text-xs">Settings</span>
</button>
<button class="app text-white flex flex-col items-center justify-center rounded-xl p-2 hover:bg-red-100 transition transform hover:scale-105">
<img src="img/apps/mail.png" alt="Mail" class="w-10 h-10 mb-1"/>
<span class="text-xs">Mail</span>
</button>
<button class="app text-white flex flex-col items-center justify-center rounded-xl p-2 hover:bg-pink-100 transition transform hover:scale-105">
<img src="img/apps/music.png" alt="Music" class="w-10 h-10 mb-1"/>
<span class="text-xs">Music</span>
</button>
</div>
</div>
<!-- Dock -->
<div class="h-20 bg-gray-200 flex justify-around items-center p-2 rounded-t-3xl relative z-10">
<button class="flex flex-col items-center text-gray-600 hover:text-blue-500">
<img src="img/apps/phone.png" class="w-8 h-8 mb-1"/>
<span class="text-xs">Phone</span>
</button>
<button class="flex flex-col items-center text-gray-600 hover:text-blue-500">
<img src="img/apps/messages.png" class="w-8 h-8 mb-1"/>
<span class="text-xs">Messages</span>
</button>
<button class="flex flex-col items-center text-gray-600 hover:text-blue-500">
<img src="img/apps/browser.png" class="w-8 h-8 mb-1"/>
<span class="text-xs">Browser</span>
</button>
<button class="flex flex-col items-center text-gray-600 hover:text-blue-500">
<img src="img/apps/settings.png" class="w-8 h-8 mb-1"/>
<span class="text-xs">Settings</span>
</button>
</div>
</div>
<script src="app.js"></script>
</body>

View File

@@ -0,0 +1,5 @@
#wallpaper {
background-image: url('img/wallpapers/wallpaper-02.png');
background-size: cover;
background-position: center;
}

103
html/test.js Normal file
View File

@@ -0,0 +1,103 @@
let dragging = false;
let offsetX = 0;
let offsetY = 0;
const phoneEl = document.getElementById('phone');
phoneEl.addEventListener('mousedown', e => {
if (e.target.closest('.message-input') || e.target.closest('input') || e.target.closest('button')) return;
dragging = true;
phoneEl.classList.add('dragging');
const rect = phoneEl.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
});
window.addEventListener('mousemove', e => {
if (!dragging) return;
phoneEl.style.left = `${e.clientX - offsetX}px`;
phoneEl.style.top = `${e.clientY - offsetY}px`;
});
window.addEventListener('mouseup', () => {
if (!dragging) return;
dragging = false;
phoneEl.classList.remove('dragging');
});
window.addEventListener('message', function(event) {
const d = event.data;
if (!d) return;
if (d.action === 'toggle') {
const phone = document.getElementById('phone');
if (d.open) {
phone.classList.remove('hidden');
updateTime();
} else {
phone.classList.add('hidden');
}
} else if (d.action === 'receiveMessage') {
appendMessage(d.from, d.message, 'from');
}
});
document.getElementById('closeBtn').addEventListener('click', function() {
fetch(`https://${GetParentResourceName()}/close`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
});
document.getElementById('messagesApp').addEventListener('click', function() {
document.getElementById('home').style.display = 'none';
document.getElementById('messages').style.display = 'flex';
});
document.getElementById('sendBtn').addEventListener('click', sendMessage);
document.getElementById('msgInput').addEventListener('keydown', function(e) {
if (e.key === 'Enter') sendMessage();
});
function sendMessage() {
const input = document.getElementById('msgInput');
const v = input.value.trim();
if (!v) return;
appendMessage('You', v, 'me');
fetch(`https://${GetParentResourceName()}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: v })
}).then(res => res.json()).then(() => {
input.value = '';
});
}
function appendMessage(sender, text, cls) {
const list = document.getElementById('messagesList');
const el = document.createElement('div');
el.className = 'msg ' + (cls || '');
el.innerText = sender + ': ' + text;
list.appendChild(el);
list.scrollTop = list.scrollHeight;
}
function updateTime() {
const t = document.getElementById('time');
const now = new Date();
const hh = String(now.getHours()).padStart(2, '0');
const mm = String(now.getMinutes()).padStart(2, '0');
t.innerText = hh + ':' + mm;
}
function GetParentResourceName() {
try {
return new URL(document.location).searchParams.get('parent') || window.parentResource || 'gb-phone';
} catch (e) {
return 'gb-phone';
}
}