Skip to content

Commit 75dc438

Browse files
committed
Fix PFP error
1 parent 039f0b8 commit 75dc438

4 files changed

Lines changed: 101 additions & 59 deletions

File tree

js/main.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,17 +132,17 @@ function syncPublicProfileFromPost(uid, profile = {}) {
132132
profileUid: normalizedUid,
133133
username,
134134
displayName,
135-
title: existing.title || profile.title || "Noctive User",
136-
status: existing.status || profile.status || "Online",
137-
bio: stripLegacyBio(existing.bio || profile.bio || ""),
138-
theme: existing.theme || profile.theme || "default",
139-
avatar: existing.avatar ?? profile.avatar ?? "",
140-
bannerTitle: existing.bannerTitle || profile.bannerTitle || getBannerHeadline(username, displayName),
135+
title: profile.title || existing.title || "Noctive User",
136+
status: profile.status || existing.status || "Online",
137+
bio: stripLegacyBio(profile.bio || existing.bio || ""),
138+
theme: profile.theme || existing.theme || "default",
139+
avatar: profile.avatar ?? existing.avatar ?? "",
140+
bannerTitle: profile.bannerTitle || existing.bannerTitle || getBannerHeadline(username, displayName),
141141
bannerText:
142-
existing.bannerText ||
143142
profile.bannerText ||
143+
existing.bannerText ||
144144
"",
145-
bannerTags: existing.bannerTags || profile.bannerTags || ["Noctive"],
145+
bannerTags: profile.bannerTags || existing.bannerTags || ["Noctive"],
146146
stats: existing.stats || {
147147
posts: 0,
148148
followers: 0,

js/page-loader.js

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
".noctive-loader-overlay { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; background: radial-gradient(circle at 50% 30%, rgba(71, 66, 121, 0.26), rgba(11, 12, 25, 0.97) 62%), linear-gradient(180deg, #15142a 0%, #0b0b17 100%); opacity: 1; transition: opacity 220ms ease; }",
1212
".noctive-loader-overlay.is-exiting { opacity: 0; pointer-events: none; }",
1313
".noctive-loader-shell { display: grid; justify-items: center; gap: 18px; padding: 28px 30px 24px; border-radius: 28px; border: 1px solid rgba(255,255,255,0.08); background: linear-gradient(180deg, rgba(29, 28, 54, 0.96), rgba(17, 17, 31, 0.96)); box-shadow: 0 24px 80px rgba(0,0,0,0.42); }",
14-
".noctive-loader-cat-frame { width: 180px; height: 136px; display: grid; place-items: center; border-radius: 24px; background: linear-gradient(180deg, #fbfbff 0%, #eef0f8 100%); box-shadow: inset 0 0 0 1px rgba(19, 22, 41, 0.06); overflow: hidden; }",
15-
".noctive-loader-cat { width: 124px; height: 100px; transform-origin: center bottom; animation: noctiveLoaderBob 900ms ease-in-out infinite; image-rendering: pixelated; }",
14+
".noctive-loader-cat-frame { width: 180px; height: 136px; display: grid; place-items: center; border-radius: 24px; background: transparent; box-shadow: none; overflow: hidden; }",
15+
".noctive-loader-cat { width: 124px; height: 100px; object-fit: contain; transform-origin: center bottom; animation: noctiveLoaderBob 900ms ease-in-out infinite; image-rendering: pixelated; }",
1616
".noctive-loader-copy { font-family: 'Inter', system-ui, sans-serif; font-size: 0.95rem; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255,255,255,0.76); }",
1717
".noctive-loader-copy strong { color: #ffd763; font-weight: 700; }",
1818
"@keyframes noctiveLoaderBob { 0%, 100% { transform: translateY(0px); } 50% { transform: translateY(-4px); } }"
@@ -28,33 +28,7 @@
2828
overlay.innerHTML = [
2929
'<div class="noctive-loader-shell">',
3030
' <div class="noctive-loader-cat-frame">',
31-
' <svg class="noctive-loader-cat" viewBox="0 0 124 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">',
32-
' <rect width="124" height="100" fill="transparent"/>',
33-
' <rect x="18" y="54" width="18" height="28" fill="#3c4250"/>',
34-
' <rect x="22" y="50" width="10" height="8" fill="#3c4250"/>',
35-
' <rect x="24" y="46" width="6" height="6" fill="#3c4250"/>',
36-
' <rect x="14" y="58" width="6" height="18" fill="#596273"/>',
37-
' <rect x="28" y="58" width="6" height="20" fill="#596273"/>',
38-
' <rect x="40" y="28" width="40" height="38" fill="#70798b"/>',
39-
' <rect x="36" y="32" width="8" height="18" fill="#70798b"/>',
40-
' <rect x="80" y="32" width="8" height="18" fill="#70798b"/>',
41-
' <rect x="44" y="20" width="10" height="10" fill="#70798b"/>',
42-
' <rect x="70" y="20" width="10" height="10" fill="#70798b"/>',
43-
' <rect x="48" y="24" width="4" height="4" fill="#fbfbff"/>',
44-
' <rect x="72" y="24" width="4" height="4" fill="#fbfbff"/>',
45-
' <rect x="48" y="34" width="6" height="6" fill="#2b2f3a"/>',
46-
' <rect x="70" y="34" width="6" height="6" fill="#2b2f3a"/>',
47-
' <rect x="58" y="44" width="4" height="4" fill="#2b2f3a"/>',
48-
' <rect x="62" y="44" width="4" height="4" fill="#2b2f3a"/>',
49-
' <rect x="54" y="52" width="16" height="4" fill="#596273"/>',
50-
' <rect x="46" y="66" width="8" height="22" fill="#596273"/>',
51-
' <rect x="70" y="66" width="8" height="22" fill="#596273"/>',
52-
' <rect x="52" y="64" width="20" height="20" fill="#7d8698"/>',
53-
' <rect x="78" y="58" width="20" height="22" fill="#4a5161"/>',
54-
' <rect x="96" y="52" width="10" height="10" fill="#4a5161"/>',
55-
' <rect x="90" y="74" width="8" height="14" fill="#596273"/>',
56-
' <rect x="98" y="74" width="8" height="14" fill="#596273"/>',
57-
' </svg>',
31+
' <img class="noctive-loader-cat" src="/gifs/Hazel.gif" alt="Hazel loading animation">',
5832
' </div>',
5933
' <div class="noctive-loader-copy"><strong>Noctive</strong> loading</div>',
6034
'</div>'

pages/edit-profile.html

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,10 @@
256256
inset: 0;
257257
z-index: 2;
258258
display: flex;
259-
align-items: flex-start;
260-
justify-content: flex-end;
261-
padding: 14px;
262-
background: rgba(10,10,14,0.10);
259+
align-items: center;
260+
justify-content: center;
261+
padding: 12px;
262+
background: rgba(10,10,14,0.18);
263263
opacity: 0;
264264
transition: opacity 0.18s ease;
265265
pointer-events: none;
@@ -273,14 +273,21 @@
273273
}
274274
.media-btn {
275275
border-radius: 999px;
276-
border: 1px solid rgba(255,255,255,0.14);
277-
background: rgba(12,13,20,0.82);
276+
border: 2px solid rgba(255,255,255,0.78);
277+
background: rgba(12,13,20,0.88);
278278
color: #fff;
279-
padding: 8px 12px;
279+
padding: 10px 16px;
280280
font-family: var(--font-head);
281-
font-size: 0.84rem;
281+
font-size: 0.95rem;
282+
font-weight: 700;
283+
line-height: 1.05;
284+
text-align: center;
285+
box-shadow: 0 12px 30px rgba(0,0,0,0.28);
282286
cursor: pointer;
283287
}
288+
.preview-avatar-shell .media-hover {
289+
border-radius: 50%;
290+
}
284291
.preview-copy {
285292
position: absolute;
286293
left: 16px;
@@ -1083,7 +1090,9 @@ <h2 id="previewBannerTitle">Your Noctive profile starts here.</h2>
10831090

10841091
if (applyBtn) {
10851092
applyBtn.disabled = pendingMediaUploadState === 'error' || (!hasValue && pendingMediaUploadState !== 'uploading');
1086-
applyBtn.textContent = pendingMediaUploadState === 'uploading' ? 'Applying After Upload...' : 'Apply Media';
1093+
applyBtn.textContent = pendingMediaUploadState === 'uploading'
1094+
? 'Uploading...'
1095+
: (hasValue ? 'Done' : 'Apply Media');
10871096
}
10881097

10891098
if (removeBtn) {
@@ -1132,6 +1141,21 @@ <h2 id="previewBannerTitle">Your Noctive profile starts here.</h2>
11321141
document.getElementById('mediaModal')?.setAttribute('hidden', 'hidden');
11331142
}
11341143

1144+
async function persistMediaFields(patch, successMessage = 'Profile media updated.') {
1145+
if (!patch || typeof patch !== 'object') return;
1146+
1147+
const nextProfile = deepMerge(getStoredProfile(currentAuthUser), patch);
1148+
localStorage.setItem(getProfileStorageKey(currentAuthUser), JSON.stringify(nextProfile));
1149+
1150+
if (currentAuthUser?.uid) {
1151+
syncPublicProfile(currentAuthUser.uid, nextProfile, currentAuthUser);
1152+
}
1153+
1154+
await syncProfileDocument(nextProfile);
1155+
updatePreview(readFormProfile());
1156+
setSaveMessage(successMessage, 'good saved-pop');
1157+
}
1158+
11351159
function applyMediaValue(value, options = {}) {
11361160
const fieldId = activeMediaTarget === 'bannerImage' ? 'bannerImage' : 'avatar';
11371161
const { previewValue = value, persist = true } = options;
@@ -1144,9 +1168,9 @@ <h2 id="previewBannerTitle">Your Noctive profile starts here.</h2>
11441168
if (persist) {
11451169
input.value = value || '';
11461170
profileMediaStoragePaths[fieldId] = value ? pendingMediaStoragePath : '';
1171+
markDirty();
11471172
}
11481173
setPreviewMediaOverride(fieldId, previewValue || '');
1149-
markDirty();
11501174
setSaveMessage(persist ? 'Media applied to the preview. Save Profile to keep it.' : 'Media preview updated. Upload is still finishing in the background.', 'good');
11511175
updatePreview(readFormProfile());
11521176
}
@@ -1165,7 +1189,17 @@ <h2 id="previewBannerTitle">Your Noctive profile starts here.</h2>
11651189
applyMediaValue('');
11661190
setMediaPreview('');
11671191
updateMediaActionState();
1168-
closeMediaModal();
1192+
const patch = activeMediaTarget === 'bannerImage'
1193+
? { bannerImage: '', bannerStoragePath: '' }
1194+
: { avatar: '', avatarStoragePath: '' };
1195+
Promise.resolve(persistMediaFields(patch, activeMediaTarget === 'bannerImage' ? 'Banner removed and saved.' : 'Profile picture removed and saved.'))
1196+
.catch((error) => {
1197+
console.error('Could not save removed media:', error);
1198+
setSaveMessage('Could not save that media change. Try again.', 'bad');
1199+
})
1200+
.finally(() => {
1201+
closeMediaModal();
1202+
});
11691203
});
11701204
document.getElementById('mediaFile')?.addEventListener('change', async (event) => {
11711205
const file = event.target.files?.[0];
@@ -1199,7 +1233,18 @@ <h2 id="previewBannerTitle">Your Noctive profile starts here.</h2>
11991233
pendingMediaUploadState = 'ready';
12001234
setMediaPreview(uploadedMedia.url);
12011235
applyMediaValue(uploadedMedia.url, { previewValue: uploadedMedia.url, persist: true });
1202-
setSaveMessage(currentAuthUser?.uid ? 'Upload finished and media is applied to the preview. Save Profile to keep it.' : 'Image loaded and applied to the preview. Save Profile to keep it.', 'good');
1236+
if (uploadTarget === 'bannerImage') {
1237+
await persistMediaFields({
1238+
bannerImage: uploadedMedia.url,
1239+
bannerStoragePath: uploadedMedia.storagePath
1240+
}, currentAuthUser?.uid ? 'Banner uploaded and published.' : 'Banner updated for this browser preview.');
1241+
} else {
1242+
await persistMediaFields({
1243+
avatar: uploadedMedia.url,
1244+
avatarStoragePath: uploadedMedia.storagePath
1245+
}, currentAuthUser?.uid ? 'Profile picture uploaded and published.' : 'Profile picture updated for this browser preview.');
1246+
}
1247+
closeMediaModal();
12031248
} catch (error) {
12041249
if (requestId !== pendingMediaRequestId) {
12051250
return;
@@ -1217,7 +1262,7 @@ <h2 id="previewBannerTitle">Your Noctive profile starts here.</h2>
12171262
});
12181263
document.getElementById('applyMediaBtn')?.addEventListener('click', async () => {
12191264
if (pendingMediaUploadState === 'uploading') {
1220-
setSaveMessage('Upload is still finishing. Applying as soon as it completes...', 'remind');
1265+
setSaveMessage('Upload is still finishing. Hang tight for one sec.', 'remind');
12211266
try {
12221267
await pendingMediaUploadPromise;
12231268
} catch (error) {
@@ -1229,12 +1274,7 @@ <h2 id="previewBannerTitle">Your Noctive profile starts here.</h2>
12291274
setSaveMessage('Preview is updated, but the upload has not finished yet. Give it another moment before saving.', 'remind');
12301275
return;
12311276
}
1232-
applyMediaValue(value, { previewValue: pendingMediaPreviewValue || value, persist: true });
1233-
const avatarValue = document.getElementById('avatar')?.value.trim() || '';
1234-
const bannerValue = document.getElementById('bannerImage')?.value.trim() || '';
1235-
if ((activeMediaTarget === 'avatar' && avatarValue === value) || (activeMediaTarget === 'bannerImage' && bannerValue === value) || !value) {
1236-
closeMediaModal();
1237-
}
1277+
closeMediaModal();
12381278
});
12391279
document.getElementById('mediaModal')?.addEventListener('click', (event) => {
12401280
if (event.target.id === 'mediaModal') closeMediaModal();

pages/profile.html

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,27 @@ <h2 id="profileDisplayName">Guest</h2>
17311731
return getFollowingSet(uid).size;
17321732
}
17331733

1734+
function hasStoredFollowingSet(uid) {
1735+
const normalizedUid = normalizeUid(uid);
1736+
if (!normalizedUid) return false;
1737+
1738+
try {
1739+
return localStorage.getItem(buildFollowingStorageKey(normalizedUid)) !== null;
1740+
} catch (error) {
1741+
console.error('Could not check following storage:', error);
1742+
return false;
1743+
}
1744+
}
1745+
1746+
function getResolvedFollowingCount(uid, fallbackCount = 0) {
1747+
const normalizedUid = normalizeUid(uid);
1748+
if (!normalizedUid) return Number(fallbackCount ?? 0);
1749+
if (hasStoredFollowingSet(normalizedUid)) {
1750+
return getFollowingCount(normalizedUid);
1751+
}
1752+
return Number(fallbackCount ?? 0);
1753+
}
1754+
17341755
function syncFollowButton(view) {
17351756
const followBtn = document.getElementById('profileFollowBtn');
17361757
if (!followBtn) return;
@@ -1901,6 +1922,12 @@ <h2 id="profileDisplayName">Guest</h2>
19011922
const directory = getPublicProfileDirectory();
19021923
directory[normalizedUid] = normalizeProfileBadges(stripLegacyProfileCopy(deepMerge(PROFILE_TEMPLATE, {
19031924
...profile,
1925+
stats: {
1926+
...PROFILE_TEMPLATE.stats,
1927+
...(profile.stats || {}),
1928+
followers: getFollowerCount(normalizedUid),
1929+
following: getResolvedFollowingCount(normalizedUid, profile.stats?.following ?? PROFILE_TEMPLATE.stats.following)
1930+
},
19041931
username: profile.username || user?.email?.split('@')[0] || normalizedUid,
19051932
displayName: profile.displayName || user?.displayName || normalizedUid,
19061933
profileUid: normalizedUid
@@ -2377,9 +2404,10 @@ <h2 id="profileDisplayName">Guest</h2>
23772404
});
23782405
const normalizedProfileUid = normalizeUid(uid);
23792406
const followerCount = getFollowerCount(normalizedProfileUid);
2380-
const followingCount = isOwnProfile
2381-
? getFollowingCount(normalizedProfileUid)
2382-
: Number(profile.stats?.following ?? 0);
2407+
const followingCount = getResolvedFollowingCount(
2408+
normalizedProfileUid,
2409+
profile.stats?.following ?? 0
2410+
);
23832411

23842412
const bannerFill = document.getElementById('bannerFill');
23852413
if (bannerFill) {

0 commit comments

Comments
 (0)