-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
145 lines (132 loc) · 8.83 KB
/
index.html
File metadata and controls
145 lines (132 loc) · 8.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mastodon Wraps Importer</title>
<meta name="description" content="Importiere deine Mastodon Toots und erstelle ein persönliches Mastodon Wrapped mit Statistiken">
<meta name="author" content="54GradSoftware & Samuel Brinkmann">
<meta name="keywords" content="Mastodon, Wrapped, Statistics, Social Media, Analytics">
<meta property="og:title" content="Mastodon Wrapped - Deine Jahresstatistik">
<meta property="og:description" content="Importiere deine Mastodon Toots und erstelle dein persönliches Wrapped">
<meta property="og:type" content="website">
<meta name="fediverse:creator" content="@sabrinkmann@hachyderm.io">
<script src="/libs/vue.global.prod.min.js"></script>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<div id="app">
<div class="card">
<h1>🦣 Mastodon Wraps {{new Date().getFullYear()}} #mastodonWraps25</h1>
<p class="subtitle">Importiere alle deine Toots des letzten Jahres und erstelle dein <a href="https://joinmastodon.org/de">Mastodon</a> Wraps! Alle Toots werden lokal in deinem Browser gespeichert und verarbeitet. Das Tool ist mit allen ActivityPub-Software kompatibel, die mit der Mastodon-API kompatibel ist. Immer werden die Toots der letzten 365 Tage importiert und ausgewertet. Erstellt von <a href="https://hachyderm.io/@sabrinkmann" target="_blank">@sabrinkmann@hachyderm.io</a> und <a href="https://norden.social/@54gradsoftware" target="_blank">@54gradsoftware@norden.social</a>. Veröffentlicht unter AGPL auf <a href="https://github.com/54GradSoftware/mastodon-wraps" target="_blank">GitHub.</a></p>
<!-- Login-Formular -->
<div v-if="!isAuthenticated">
<article>Bevor wir dein Mastodon Wraps erstellen können musst du dich mit deiner Mastodon-Instanz verbinden. Dafür musst du erst deine Mastodon Instanz URL eingeben. Dann wirst du weitergeleitet und kannst dich authentifizieren. Wir brauchen eine Leseberechtigung auf deine Toots, um die Daten zu importieren. Alle Daten aus Mastodon werden lokal in deinem Browser gespeichert und nicht an Dritte weitergegeben. Anschließen kannst du dann deinen Mastodon Wraps erstellen.</article>
<div class="form-group">
<label for="instance">Mastodon Instanz URL</label>
<input
type="text"
id="instance"
v-model="instanceUrl"
placeholder="z.B. mastodon.social"
@keyup.enter="startAuth"
>
</div>
<button @click="startAuth" :disabled="!instanceUrl || isLoading">
<span v-if="isLoading" class="loading-spinner"></span>
<span v-else>🔌 Mit Mastodon verbinden</span>
</button>
<div v-if="error" class="error">{{ error }}</div>
</div>
<!-- Import-Bereich -->
<div v-else>
<div class="success">✓ Erfolgreich mit {{ instanceUrl }} verbunden als @{{ username }}</div>
<!-- Existierende Toots Anzeige -->
<div v-if="existingTootsCount > 0 && !importComplete">
<div class="success" style="margin-top: 20px;">
📊 {{ existingTootsCount }} (Re-)Toots bereits in der Datenbank vorhanden
</div>
<button @click="generateWrapped" style="margin-top: 20px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">🎉 Wrapped generieren</button>
<button @click="startImport" :disabled="isImporting" style="margin-top: 20px; margin-left: 10px;">
<span v-if="isImporting" class="loading-spinner"></span>
<span v-else>📩 Neue Toots importieren</span>
</button>
<button @click="viewToots" style="margin-top: 20px; margin-left: 10px;">📬 Toots anzeigen</button>
<button @click="resetApp" style="margin-top: 20px; margin-left: 10px; background: #111;">🔃 Neu starten</button>
</div>
<div v-else-if="existingTootsCount === 0 && !importComplete">
<button @click="startImport" :disabled="isImporting" style="margin-top: 20px;">
<span v-if="isImporting" class="loading-spinner"></span>
<span v-else>Import starten</span>
</button>
<div v-if="isImporting" class="progress-container">
<div class="progress-bar">
<div class="progress-fill" :style="{width: importProgress + '%'}">
{{ importProgress }}%
</div>
</div>
<div class="status-text">{{ statusText }}</div>
</div>
</div>
<div v-if="importComplete">
<div class="success">✓ Import abgeschlossen!</div>
<div class="stats">
<div class="stat-box">
<div class="stat-number">{{ totalToots }}</div>
<div class="stat-label">Toots importiert</div>
</div>
<div class="stat-box">
<div class="stat-number">{{ Math.round(importTime / 1000) }}s</div>
<div class="stat-label">Dauer</div>
</div>
</div>
<button @click="viewToots" style="margin-top: 20px;">Toots anzeigen</button>
<button @click="generateWrapped" style="margin-top: 20px; margin-left: 10px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">🎉 Wrapped generieren</button>
<button @click="resetApp" style="margin-top: 20px; margin-left: 10px; background: #999;">Neu starten</button>
</div>
<div v-if="error" class="error">{{ error }}</div>
</div>
</div>
<!-- Toot-Anzeige -->
<div class="card" v-if="showToots && toots.length > 0">
<h2>Deine Toots ({{ toots.length }})</h2>
<div class="toot-list">
<div v-for="toot in toots" :key="toot.id" class="toot-item">
<div class="toot-date">{{ formatDate(toot.created_at) }}</div>
<div class="toot-content" v-html="toot.content"></div>
</div>
</div>
</div>
<!-- Wrapped Anzeige -->
<div class="card" v-if="wrappedData">
<h2>🎉 Dein Mastodon Wrapped {{ new Date().getFullYear() }}</h2>
<div class="wrapped-container" style="width: 100%;">
<div v-for="card in cardsList" :key="card" style="width: 100%; margin-bottom: 20px;">
<canvas :id="'canvas-' + card" style="width: 100%;"></canvas>
<button class="download-btn" @click="downloadWrappedCard(card)">💾 Download</button>
<label :for="'example-alttext-' + card">Beispiel Alternativtext</label>
<input :id="'example-alttext-' + card" :value="cardsValue[card]?.altText" placeholder="Alternativtext für Barrierefreiheit" style="width: 100%; margin-top: 10px; padding: 8px; border: 1px solid #ccc; border-radius: 4px;">
</div>
</div>
<div class="wrapped-actions">
<button @click="downloadAllCards">📥 Alle herunterladen</button>
</div>
</div>
<!-- Generierungs-Overlay -->
<div v-if="isGenerating" class="generating-overlay">
<div class="generating-spinner"></div>
<div class="generating-text">Erstelle dein Wrapped...</div>
</div>
<a href="https://www.54gradsoftware.de" target="_blank" class="impressum-link">54 Grad Software GmbH</a> |
<a href="https://www.54gradsoftware.de/impressum" target="_blank" class="impressum-link">Impressum</a> |
<a href="https://www.54gradsoftware.de/datenschutz" target="_blank" class="impressum-link">Datenschutz</a> | Zum Datensparsamen Analyse nutzt diese Anwendung <a href="https://plausible.io" target="_blank" class="impressum-link">Plausible Analytics</a>
</div>
<script src="/main.js"></script>
<!-- Privacy-friendly analytics by Plausible -->
<script async src="https://plausible.io/js/pa-8edjAGJLZ2C6eZ15_xpKu.js"></script>
<script>
window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
plausible.init()
</script>
</body>
</html>