Self-hosted, federated location sharing app and server that prioritizes user privacy and security
end-to-end-encryption
location-sharing
privacy
self-hosted
federated
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <script type="module" src="./home.ts"></script>
6 <link rel="stylesheet" href="./home.css" />
7 </head>
8
9 <body>
10 <div class="app" x-data="homePageState">
11 <!-- Header -->
12 <header>
13 <h1>PrivacyPin</h1>
14 <div>
15 <!-- <@azom.dev> somehow the "+" emoji does not display in the code for me, but it's temporary anyways -->
16 <!-- <@kishka.cc> we will need to replace these with svgs, as it's the font that messes up the emoji -->
17 <button class="icon-btn" @click="updateServer()">
18 <img class="svg-icon" src="/src/assets/paperplane.svg" alt="Paperplane Flying Icon" />
19 </button>
20 <button class="icon-btn" @click="addFriend()">
21 <img class="svg-icon" src="/src/assets/user+.svg" alt="Friend Add Icon" />
22 </button>
23 <button class="icon-btn" @click="openSettings()">
24 <img class="svg-icon" src="/src/assets/setting.svg" alt="Settings Icon" />
25 </button>
26 </div>
27 </header>
28
29 <!-- Status -->
30 <div class="status">
31 <span>Last ping sent:</span>
32 <!-- later, figure out how to update this cleanly when we will have the actual data -->
33 <span x-text="timeAgo()"></span>
34 </div>
35
36 <!-- Friends -->
37 <div class="content">
38 <div class="friends-header">
39 <h2 style="font-size: 1rem; margin: 0">Friends</h2>
40 <span style="color: #6b7280; font-size: 0.9rem">(<span x-text="friends.length"></span>)</span>
41 </div>
42 <!--TODO idk why but sometimes when i launch the app I see the stuff when you have no friends for a split second before I see them appear, even tho we get them in init -->
43 <template x-if="friends.length > 0">
44 <div>
45 <template x-for="friend in friends" :key="friend.id">
46 <div class="friend-card">
47 <strong x-text="friend.name"></strong>
48 <div class="friend-actions">
49 <button class="view-btn" @click="viewLocation(friend.id)"><img class="svg-icon" src="/src/assets/pin-location.svg" alt="Pin Icon" />View</button>
50
51 <button class="menu-icon" style="margin-bottom: auto" @click="friendOptions(friend.id)">
52 <img class="svg-icon" src="/src/assets/ellipsis-vertical.svg" alt="Options menu" />
53 </button>
54 </div>
55 </div>
56 </template>
57 </div>
58 </template>
59
60 <template x-if="friends.length === 0">
61 <div class="empty-state">
62 <div style="font-size: 2rem">👥</div>
63 <h3>No friends yet</h3>
64 <p>Add friends to start sharing locations</p>
65 <button @click="addFriend()">Add Friend</button>
66 </div>
67 </template>
68 </div>
69
70 <!-- Admin -->
71 <div x-show="is_admin">
72 <div class="content" style="text-align: center">
73 <h4>Admin Controls:</h4>
74 <div style="display: flex; justify-content: center">
75 <button @click="generateSignupKey()">Generate signup key</button>
76 </div>
77 <div style="display: flex; justify-content: center" x-show="newSignupKey != ''">
78 <p>New signup key: <a x-text="newSignupKey"></a></p>
79 </div>
80 </div>
81 </div>
82 </div>
83 </body>
84</html>