Added UI
@@ -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'
|
||||
|
||||
75
html/app.js
@@ -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
|
After Width: | Height: | Size: 11 KiB |
BIN
html/img/apps/camera.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 19 KiB |
BIN
html/img/apps/mail.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 4.8 KiB |
BIN
html/img/apps/music.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
html/img/apps/phone.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
html/img/apps/photos.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
html/img/apps/settings.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
html/img/wallpapers/wallpaper-01.png
Normal file
|
After Width: | Height: | Size: 3.0 MiB |
BIN
html/img/wallpapers/wallpaper-02.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
@@ -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">
|
||||
×
|
||||
</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>
|
||||
|
||||
@@ -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
@@ -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';
|
||||
}
|
||||
}
|
||||