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
19 class="svg-icon"
20 src="/src/assets/paperplane.svg"
21 alt="Paperplane Flying Icon"
22 />
23 </button>
24 <button class="icon-btn" @click="addFriend()">
25 <img
26 class="svg-icon"
27 src="/src/assets/user+.svg"
28 alt="Friend Add Icon"
29 />
30 </button>
31 <button class="icon-btn" @click="openSettings()">
32 <img
33 class="svg-icon"
34 src="/src/assets/setting.svg"
35 alt="Settings Icon"
36 />
37 </button>
38 </div>
39 </header>
40
41 <!-- Status -->
42 <div class="status">
43 <span>Last ping sent:</span>
44 <!-- later, figure out how to update this cleanly when we will have the actual data -->
45 <span x-text="timeAgo()"></span>
46 </div>
47
48 <!-- Friends -->
49 <div class="content">
50 <div class="friends-header">
51 <h2 style="font-size: 1rem; margin: 0">Friends</h2>
52 <span style="color: #6b7280; font-size: 0.9rem"
53 >(<span x-text="friends.length"></span>)</span
54 >
55 </div>
56 <!--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 -->
57 <template x-if="friends.length > 0">
58 <div>
59 <template x-for="friend in friends" :key="friend.id">
60 <div class="friend-card">
61 <strong x-text="friend.name"></strong>
62 <div class="friend-actions">
63 <button
64 class="view-btn"
65 @click="viewLocation(friend.id)"
66 >
67 <img
68 class="svg-icon"
69 src="/src/assets/pin-location.svg"
70 alt="Pin Icon"
71 />View
72 </button>
73
74 <button
75 class="menu-icon"
76 style="margin-bottom: auto"
77 @click="friendOptions(friend.id)"
78 >
79 <img
80 class="svg-icon"
81 src="/src/assets/ellipsis-vertical.svg"
82 alt="Options menu"
83 />
84 </button>
85 </div>
86 </div>
87 </template>
88 </div>
89 </template>
90
91 <template x-if="friends.length === 0">
92 <div class="empty-state">
93 <div style="font-size: 2rem">👥</div>
94 <h3>No friends yet</h3>
95 <p>Add friends to start sharing locations</p>
96 <button @click="addFriend()">Add Friend</button>
97 </div>
98 </template>
99 </div>
100
101 <!-- Admin -->
102 <div x-show="is_admin">
103 <div class="content" style="text-align: center">
104 <h4>Admin Controls:</h4>
105 <div style="display: flex; justify-content: center">
106 <button @click="generateSignupKey()">
107 Generate signup key
108 </button>
109 </div>
110 <div
111 style="display: flex; justify-content: center"
112 x-show="newSignupKey != ''"
113 >
114 <p>New signup key: <a x-text="newSignupKey"></a></p>
115 </div>
116 </div>
117 </div>
118 </div>
119 </body>
120</html>