From 11cbc0cbb53aceca35512068d6f0d5d3fad365a5 Mon Sep 17 00:00:00 2001 From: Ujwal223 Date: Sun, 18 Oct 2026 15:09:33 +0545 Subject: [PATCH] Port(89% Done): # Problem Fixes - A LOT (feeling lazy) # New - > Chat Security & Messages Lock > Dynamic App Icons & Historical Originals: and few more... # Known Problems: > Hide Likes Count doesnt work. there can be more bugs as v3 is incomplete. --- Ported/app/src/main/AndroidManifest.xml | 191 ++- .../assets/extensions/ublock/background.js | 196 ++- .../main/assets/extensions/ublock/content.js | 3 + .../extensions/ublock/focusgram_content.js | 1178 ++++++++++++++++- .../main/assets/scripts/fetch_interceptor.js | 587 +++++++- .../src/main/assets/scripts/native_feel.js | 326 ++++- .../com/ujwal/focusgram/MainActivity.kt | 8 + .../core/datastore/SettingsRepository.kt | 135 ++ .../focusgram/core/engine/ExtensionManager.kt | 113 +- .../engine/FocusGramNavigationDelegate.kt | 19 + .../core/engine/GeckoSessionManager.kt | 16 +- .../core/engine/UserScriptManager.kt | 20 + .../focusgram/core/model/FocusSettings.kt | 10 + .../ujwal/focusgram/core/model/IslandMode.kt | 2 +- .../core/security/EncryptedStorage.kt | 42 + .../focusgram/core/utils/AppIconManager.kt | 285 ++++ .../core/utils/HistoricalIconManager.kt | 156 +++ .../feature/applock/AppLockScreen.kt | 43 +- .../feature/applock/AppLockSettingsPage.kt | 148 +-- .../feature/applock/AppLockSetupScreen.kt | 16 +- .../feature/applock/ChatLockScreen.kt | 463 +++++++ .../feature/history/ReelsHistoryScreen.kt | 5 +- .../feature/navigation/NativeBottomNavBar.kt | 3 +- .../feature/settings/SettingsScreen.kt | 618 ++++++++- .../feature/wellness/AdsterraAdScreen.kt | 105 +- .../com/ujwal/focusgram/ui/FocusGramApp.kt | 456 ++++++- .../ic_launcher_fg_abstract.png | Bin 0 -> 251468 bytes .../ic_launcher_fg_forest.png | Bin 0 -> 418577 bytes .../ic_launcher_fg_golden.png | Bin 0 -> 276616 bytes .../drawable-xxxhdpi/ic_launcher_fg_metal.png | Bin 0 -> 274087 bytes .../ic_launcher_fg_minimalist.png | Bin 0 -> 99566 bytes .../ic_launcher_fg_polaroid.png | Bin 0 -> 145023 bytes .../ic_launcher_fg_redesign.png | Bin 0 -> 248418 bytes .../ic_launcher_fg_scribble.png | Bin 0 -> 254032 bytes .../ic_launcher_fg_vibrant.png | Bin 0 -> 134881 bytes .../ic_launcher_fg_viewfinder.png | Bin 0 -> 148946 bytes .../main/res/drawable/ic_chat_lock_closed.xml | 9 + .../main/res/drawable/ic_chat_lock_open.xml | 9 + .../res/drawable/ic_launcher_bg_instagram.xml | 14 + .../res/drawable/ic_launcher_fg_all_white.xml | 24 + .../res/drawable/ic_launcher_fg_classic.xml | 26 + .../res/drawable/ic_launcher_fg_discreet.xml | 41 + .../ic_launcher_fg_instagram_official.xml | 24 + .../main/res/drawable/ic_launcher_fg_mono.xml | 26 + .../main/res/drawable/ic_launcher_fg_oled.xml | 26 + .../drawable/ic_launcher_fg_pitch_black.xml | 26 + .../ic_launcher_abstract.xml | 9 + .../ic_launcher_all_white.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_classic.xml | 5 + .../ic_launcher_discreet.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_forest.xml | 9 + .../mipmap-anydpi-v26/ic_launcher_golden.xml | 9 + .../ic_launcher_instagram_official.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_metal.xml | 9 + .../ic_launcher_minimalist.xml | 9 + .../mipmap-anydpi-v26/ic_launcher_mono.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_oled.xml | 5 + .../ic_launcher_pitch_black.xml | 5 + .../ic_launcher_polaroid.xml | 9 + .../ic_launcher_redesign.xml | 9 + .../ic_launcher_scribble.xml | 9 + .../mipmap-anydpi-v26/ic_launcher_vibrant.xml | 9 + .../ic_launcher_viewfinder.xml | 9 + .../mipmap-xxxhdpi/ic_launcher_abstract.png | Bin 0 -> 56962 bytes .../res/mipmap-xxxhdpi/ic_launcher_forest.png | Bin 0 -> 88564 bytes .../res/mipmap-xxxhdpi/ic_launcher_golden.png | Bin 0 -> 59961 bytes .../res/mipmap-xxxhdpi/ic_launcher_metal.png | Bin 0 -> 57902 bytes .../mipmap-xxxhdpi/ic_launcher_minimalist.png | Bin 0 -> 33357 bytes .../mipmap-xxxhdpi/ic_launcher_polaroid.png | Bin 0 -> 43889 bytes .../mipmap-xxxhdpi/ic_launcher_redesign.png | Bin 0 -> 58253 bytes .../mipmap-xxxhdpi/ic_launcher_scribble.png | Bin 0 -> 55295 bytes .../mipmap-xxxhdpi/ic_launcher_vibrant.png | Bin 0 -> 44318 bytes .../mipmap-xxxhdpi/ic_launcher_viewfinder.png | Bin 0 -> 43245 bytes Ported/app/src/main/res/values/colors.xml | 15 + .../com/ujwal/focusgram/AdsterraAdFlowTest.kt | 63 + .../ujwal/focusgram/ChatLockAndAppIconTest.kt | 208 +++ .../focusgram/UBlockExtensionAssetsTest.kt | 77 ++ alt-logos/abstract_512x512.png | Bin 0 -> 468974 bytes alt-logos/forest_512x512.png | Bin 0 -> 715657 bytes alt-logos/golden_512x512.png | Bin 0 -> 553299 bytes alt-logos/metal_512x512.png | Bin 0 -> 562637 bytes alt-logos/redesign_512x512.png | Bin 0 -> 506845 bytes alt-logos/scribble_512x512.png | Bin 0 -> 511277 bytes bottom-icons/lock-icon-closed.svg | 3 + bottom-icons/lock-icon-open.svg | 3 + 85 files changed, 5660 insertions(+), 203 deletions(-) create mode 100644 Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/AppIconManager.kt create mode 100644 Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/HistoricalIconManager.kt create mode 100644 Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/ChatLockScreen.kt create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_abstract.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_forest.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_golden.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_metal.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_minimalist.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_polaroid.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_redesign.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_scribble.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_vibrant.png create mode 100644 Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_viewfinder.png create mode 100644 Ported/app/src/main/res/drawable/ic_chat_lock_closed.xml create mode 100644 Ported/app/src/main/res/drawable/ic_chat_lock_open.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_bg_instagram.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_fg_all_white.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_fg_classic.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_fg_discreet.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_fg_instagram_official.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_fg_mono.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_fg_oled.xml create mode 100644 Ported/app/src/main/res/drawable/ic_launcher_fg_pitch_black.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_abstract.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_all_white.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_classic.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_discreet.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_forest.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_golden.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_instagram_official.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_metal.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_minimalist.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_mono.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_oled.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_pitch_black.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_polaroid.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_redesign.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_scribble.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_vibrant.xml create mode 100644 Ported/app/src/main/res/mipmap-anydpi-v26/ic_launcher_viewfinder.xml create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_abstract.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_forest.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_golden.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_metal.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_minimalist.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_polaroid.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_redesign.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_scribble.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_vibrant.png create mode 100644 Ported/app/src/main/res/mipmap-xxxhdpi/ic_launcher_viewfinder.png create mode 100644 Ported/app/src/test/kotlin/com/ujwal/focusgram/ChatLockAndAppIconTest.kt create mode 100644 alt-logos/abstract_512x512.png create mode 100644 alt-logos/forest_512x512.png create mode 100644 alt-logos/golden_512x512.png create mode 100644 alt-logos/metal_512x512.png create mode 100644 alt-logos/redesign_512x512.png create mode 100644 alt-logos/scribble_512x512.png create mode 100644 bottom-icons/lock-icon-closed.svg create mode 100644 bottom-icons/lock-icon-open.svg diff --git a/Ported/app/src/main/AndroidManifest.xml b/Ported/app/src/main/AndroidManifest.xml index e8c5cfa..12f0510 100644 --- a/Ported/app/src/main/AndroidManifest.xml +++ b/Ported/app/src/main/AndroidManifest.xml @@ -69,10 +69,6 @@ android:launchMode="singleTop" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"> - - - - @@ -94,6 +90,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Array<{pk, username, fullName, avatar, hasLiked}> + + browser.webRequest.onBeforeRequest.addListener( + function (details) { + const url = details.url || ''; + const match = url.match(/\/api\/v1\/media\/(\d+)\/list_reel_media_viewer\//); + if (!match) return; + + const mediaId = match[1]; + + // Immediately broadcast detection when request is SENT so search bar appears right away! + broadcastToTabs({ + action: 'storyViewersDetected', + phase: 'loading', + mediaId: mediaId, + url: url + }); + + if (typeof browser.webRequest.filterResponseData === 'function') { + try { + const filter = browser.webRequest.filterResponseData(details.requestId); + const chunks = []; + + filter.ondata = function (event) { + chunks.push(event.data); + filter.write(event.data); // Transparently stream data to Instagram web client + }; + + filter.onstop = async function () { + filter.close(); + try { + const blob = new Blob(chunks); + const text = await blob.text(); + const json = JSON.parse(text); + const users = json.users || []; + const rawViewers = json.viewers || []; + + const existing = storyViewersCache.get(mediaId) || []; + const userMap = new Map(existing.map(u => [String(u.pk || u.id), u])); + + users.forEach(u => { + const pk = String(u.pk || u.id); + if (!pk) return; + userMap.set(pk, { + pk: pk, + username: u.username || '', + fullName: u.full_name || '', + avatar: u.profile_pic_url || '', + isVerified: !!u.is_verified, + hasLiked: false + }); + }); + + rawViewers.forEach(v => { + const u = v.user || v; + const pk = String(u.pk || u.id); + if (!pk) return; + const existingEntry = userMap.get(pk) || {}; + userMap.set(pk, { + pk: pk, + username: u.username || existingEntry.username || '', + fullName: u.full_name || existingEntry.fullName || '', + avatar: u.profile_pic_url || existingEntry.avatar || '', + isVerified: !!(u.is_verified || existingEntry.isVerified), + hasLiked: !!(v.has_liked || existingEntry.hasLiked) + }); + }); + + const viewerList = Array.from(userMap.values()); + storyViewersCache.set(mediaId, viewerList); + console.log(`[FocusGram] Story viewers captured for ${mediaId}: ${viewerList.length} users`); + + // Broadcast captured viewers to active tabs + broadcastToTabs({ + action: 'storyViewersDetected', + phase: 'ready', + mediaId: mediaId, + viewers: viewerList + }); + broadcastToTabs({ + action: 'storyViewersCaptured', + mediaId: mediaId, + viewers: viewerList + }); + } catch (e) { + console.warn('[FocusGram] Error parsing story viewers payload:', e); + } + }; + } catch (err) { + console.warn('[FocusGram] filterResponseData error:', err); + } + } + }, + { urls: ["*://*.instagram.com/api/v1/media/*/list_reel_media_viewer/*"] }, + ["blocking"] + ); } // Establish native messaging port with FocusGram Android host let nativePort = null; +const pendingNativeMessages = []; + +function sendToNative(msg) { + if (!msg) return; + if (nativePort) { + try { + nativePort.postMessage(msg); + console.log('[FocusGram Background] Forwarded to native host:', JSON.stringify(msg)); + return; + } catch (e) { + console.warn('[FocusGram Background] postMessage failed, queueing message:', e); + nativePort = null; + } + } + pendingNativeMessages.push(msg); + if (pendingNativeMessages.length > 50) pendingNativeMessages.shift(); + connectNativePort(); +} + +function flushPendingMessages() { + if (!nativePort) return; + while (pendingNativeMessages.length > 0) { + const msg = pendingNativeMessages.shift(); + try { + nativePort.postMessage(msg); + console.log('[FocusGram Background] Flushed queued message to native host:', JSON.stringify(msg)); + } catch (e) { + console.error('[FocusGram Background] Error flushing queued message:', e); + pendingNativeMessages.unshift(msg); + break; + } + } +} function connectNativePort() { try { if (typeof browser !== 'undefined' && browser.runtime && browser.runtime.connectNative) { + if (nativePort) return; nativePort = browser.runtime.connectNative("focusgram"); console.log('[FocusGram Background] Connected to native host "focusgram"'); @@ -136,12 +274,14 @@ function connectNativePort() { nativePort.onDisconnect.addListener((p) => { console.warn('[FocusGram Background] Native port disconnected, will retry...'); nativePort = null; - setTimeout(connectNativePort, 5000); + setTimeout(connectNativePort, 3000); }); + + flushPendingMessages(); } } catch (e) { console.error('[FocusGram Background] Error connecting native port:', e); - setTimeout(connectNativePort, 5000); + setTimeout(connectNativePort, 3000); } } @@ -175,33 +315,37 @@ if (typeof browser !== 'undefined' && browser.runtime && browser.runtime.onMessa return true; } - if (!nativePort) { - connectNativePort(); + if (message.action === 'getStoryViewers') { + const mediaId = message.mediaId; + const viewers = mediaId ? (storyViewersCache.get(mediaId) || []) : []; + sendResponse({ viewers: viewers }); + return true; } - if (nativePort) { - try { - if (message.type === 'ReelMetadata' || message.action === 'reelViewed' || message.action === 'reelWatched') { - const payload = message.payload || message.data || message.reel || message; - nativePort.postMessage({ - action: 'reelViewed', - type: message.type || 'reelViewed', - code: payload.code || message.code || '', - url: payload.url || message.url || '', - title: payload.caption || payload.title || message.caption || message.title || '', - caption: payload.caption || message.caption || '', - author: payload.author || message.author || '', - thumbnailUrl: payload.thumbnailUrl || message.thumbnailUrl || '' - }); - } else { - nativePort.postMessage(message); - } - console.log('[FocusGram Background] Forwarded to native host:', JSON.stringify(message)); - } catch (e) { - console.error('[FocusGram Background] Failed to forward message to native host:', e); - } + if (message.action === 'broadcastToTabs' && message.payload) { + broadcastToTabs(message.payload); + sendResponse({ status: 'broadcasted' }); + return true; } + + if (message.type === 'ReelMetadata' || message.action === 'reelViewed' || message.action === 'reelWatched') { + const payload = message.payload || message.data || message.reel || message; + sendToNative({ + action: 'reelViewed', + type: message.type || 'reelViewed', + code: payload.code || message.code || '', + url: payload.url || message.url || '', + title: payload.caption || payload.title || message.caption || message.title || '', + caption: payload.caption || message.caption || '', + author: payload.author || message.author || '', + thumbnailUrl: payload.thumbnailUrl || message.thumbnailUrl || '' + }); + } else { + sendToNative(message); + } + sendResponse({ status: 'forwarded' }); return true; }); } + diff --git a/Ported/app/src/main/assets/extensions/ublock/content.js b/Ported/app/src/main/assets/extensions/ublock/content.js index cbeb70b..134d1f7 100644 --- a/Ported/app/src/main/assets/extensions/ublock/content.js +++ b/Ported/app/src/main/assets/extensions/ublock/content.js @@ -14,6 +14,9 @@ function isAuthPage() { try { const path = (window.location.pathname || '').toLowerCase(); + if (path.includes('/accounts/edit')) { + return false; + } if (path.startsWith('/accounts') || path.startsWith('/login') || path.startsWith('/signup')) { return true; } diff --git a/Ported/app/src/main/assets/extensions/ublock/focusgram_content.js b/Ported/app/src/main/assets/extensions/ublock/focusgram_content.js index 1e8ea06..e6d0f1c 100644 --- a/Ported/app/src/main/assets/extensions/ublock/focusgram_content.js +++ b/Ported/app/src/main/assets/extensions/ublock/focusgram_content.js @@ -33,6 +33,9 @@ function isAuthPage() { try { const path = (window.location.pathname || '').toLowerCase(); + if (path.includes('/accounts/edit')) { + return false; + } if (path.startsWith('/accounts') || path.startsWith('/login') || path.startsWith('/signup')) { return true; } @@ -557,19 +560,41 @@ const response = await originalFetch.apply(this, arguments); - // Main-World GraphQL, Clips, & Feed Ad Filtering & Reel Meta Harvesting - if (url.includes('/graphql') || url.includes('/api/v1/feed') || url.includes('/api/v1/clips/') || url.includes('/clips/')) { + // Main-World GraphQL, Clips, & Feed Ad Filtering & Reel Meta Harvesting & DM Masking + if (url.includes('/graphql') || url.includes('/api/v1/feed') || url.includes('/api/v1/clips/') || url.includes('/clips/') || url.includes('/direct/')) { try { const contentType = response.headers.get('content-type') || ''; - if (contentType.includes('application/json')) { + if (contentType.includes('json') || contentType.includes('javascript')) { const cloned = response.clone(); - const data = await cloned.json(); - walkAndFilter(data); + let data; + try { + data = await cloned.json(); + } catch (_) { + try { + let text = await cloned.text(); + text = text.replace(/^for\s*\(\s*;\s*;\s*\)\s*;\s*/, ''); + data = JSON.parse(text); + } catch (e) { + return response; + } + } + + let directModified = false; + if (typeof window.__fgProcessDirectMessagesPayload === 'function') { + directModified = window.__fgProcessDirectMessagesPayload(data); + } + + let adModified = false; if (window.__fgFilterConfig && window.__fgFilterConfig.blockAds !== false) { + walkAndFilter(data); + adModified = true; + } + + if (directModified || adModified) { const newHeaders = new Headers(response.headers); newHeaders.delete('content-length'); newHeaders.delete('content-encoding'); - newHeaders.set('content-type', 'application/json; charset=utf-8'); + newHeaders.set('content-type', contentType || 'application/json; charset=utf-8'); return new Response(JSON.stringify(data), { status: response.status, statusText: response.statusText, @@ -2176,6 +2201,9 @@ function isAnyModalOpen() { const path = window.location.pathname.toLowerCase(); + if (path.includes('/accounts/edit')) { + return false; + } // 1. Route-based detection (DM chats, stories, auth, create) if (isAuthRoute(path) || path.includes('/comments') || path.startsWith('/direct/t/') || path.startsWith('/stories/') || path.startsWith('/create')) { @@ -2276,7 +2304,580 @@ return mode; } + /* ========================================================================== + CHAT PRIVACY VEIL & INBOX PREVIEW MASKING + Zero-latency pure black cover over locked chat threads + snippet redaction. + ========================================================================== */ + let chatLockMode = 'individual'; + let chatLockAll = false; + let lockedChatIds = new Set(); + const unlockedThreads = new Set(); + const threadUsernameMap = new Map(); + + function syncGlobalsToWindow() { + const targets = [window]; + if (typeof window.wrappedJSObject !== 'undefined' && window.wrappedJSObject) { + targets.push(window.wrappedJSObject); + } + const lockedArray = Array.from(lockedChatIds); + const unlockedArray = Array.from(unlockedThreads); + const userMapObj = {}; + for (const [k, v] of threadUsernameMap.entries()) { + userMapObj[k] = v; + } + + for (const target of targets) { + try { + target.__fgChatLockMode = chatLockMode; + target.__fgChatLockAll = chatLockAll; + target.__fgLockedChatIds = lockedArray; + target.__fgUnlockedThreads = unlockedArray; + target.__fgThreadUsernameMap = userMapObj; + } catch (_) {} + } + + const syncDetail = { + chatLockMode: chatLockMode, + chatLockAll: chatLockAll, + lockedChatIds: lockedArray, + unlockedThreads: unlockedArray, + threadUsernameMap: userMapObj + }; + try { + window.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { detail: syncDetail })); + document.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { detail: syncDetail })); + } catch (_) {} + } + + function syncChatLockSettings(settings) { + if (!settings) return; + if (typeof settings.chatLockMode !== 'undefined') { + chatLockMode = String(settings.chatLockMode).toLowerCase(); + } + if (typeof settings.chatLockAll !== 'undefined') { + chatLockAll = !!settings.chatLockAll; + if (chatLockMode === 'whole_dm') { + chatLockAll = true; + } else if (chatLockMode === 'off') { + chatLockAll = false; + } + } else if (chatLockMode === 'whole_dm') { + chatLockAll = true; + } else if (chatLockMode === 'off') { + chatLockAll = false; + } + if (Array.isArray(settings.lockedChatIds)) { + lockedChatIds = new Set(settings.lockedChatIds.map(id => String(id).toLowerCase().trim().replace(/^@/, ''))); + } + if (settings.lockedChatUsernames && typeof settings.lockedChatUsernames === 'object') { + for (const [tid, uname] of Object.entries(settings.lockedChatUsernames)) { + const cleanTid = String(tid).toLowerCase().trim(); + const cleanUname = String(uname).toLowerCase().trim().replace(/^@/, ''); + if (cleanTid && cleanUname) { + threadUsernameMap.set(cleanTid, cleanUname); + threadUsernameMap.set(cleanUname, cleanTid); + if (lockedChatIds.has(cleanTid)) lockedChatIds.add(cleanUname); + if (lockedChatIds.has(cleanUname)) lockedChatIds.add(cleanTid); + } + } + } + + syncGlobalsToWindow(); + evaluateChatLockState(); + maskInboxChatPreviews(); + } + + const handleThreadMatched = (e) => { + const detail = e.detail; + if (detail && detail.threadId) { + const cleanTid = String(detail.threadId).toLowerCase().trim(); + const cleanKey = detail.threadKey ? String(detail.threadKey).toLowerCase().trim() : ''; + if (detail.isLocked) { + lockedChatIds.add(cleanTid); + if (cleanKey) lockedChatIds.add(cleanKey); + } + if (Array.isArray(detail.usernames)) { + for (const u of detail.usernames) { + const cleanUser = String(u).toLowerCase().trim().replace(/^@/, ''); + if (cleanUser) { + threadUsernameMap.set(cleanTid, cleanUser); + threadUsernameMap.set(cleanUser, cleanTid); + if (cleanKey) { + threadUsernameMap.set(cleanKey, cleanUser); + threadUsernameMap.set(cleanUser, cleanKey); + } + if (lockedChatIds.has(cleanUser)) { + lockedChatIds.add(cleanTid); + if (cleanKey) lockedChatIds.add(cleanKey); + } + if (lockedChatIds.has(cleanTid) || (cleanKey && lockedChatIds.has(cleanKey))) { + lockedChatIds.add(cleanUser); + } + } + } + } + postToNative({ + action: 'threadUsernameMapped', + threadId: cleanTid, + threadKey: cleanKey, + username: (detail.usernames && detail.usernames[0]) || '', + usernames: detail.usernames || [], + displayName: detail.displayName || '', + isLocked: !!detail.isLocked + }); + syncGlobalsToWindow(); + evaluateChatLockState(); + maskInboxChatPreviews(); + } + }; + window.addEventListener('focusgram:thread-matched', handleThreadMatched); + document.addEventListener('focusgram:thread-matched', handleThreadMatched); + + function handleUnlockChat(threadId, isAll) { + if (isAll) { + unlockedThreads.add('__all__'); + } + if (threadId) { + const clean = String(threadId).toLowerCase().trim(); + unlockedThreads.add(clean); + const mapped = threadUsernameMap.get(clean); + if (mapped) unlockedThreads.add(mapped); + } + syncGlobalsToWindow(); + removePrivacyVeil(); + evaluateChatLockState(); + maskInboxChatPreviews(); + } + + function handleLockChat(threadId) { + if (threadId) { + const clean = String(threadId).toLowerCase().trim(); + unlockedThreads.delete(clean); + const mapped = threadUsernameMap.get(clean); + if (mapped) unlockedThreads.delete(mapped); + lockedChatIds.add(clean); + if (mapped) lockedChatIds.add(mapped); + } + syncGlobalsToWindow(); + evaluateChatLockState(); + maskInboxChatPreviews(); + } + + function extractCurrentThreadId() { + const path = window.location.pathname.toLowerCase(); + if (!path.startsWith('/direct/t/')) return null; + const parts = path.replace('/direct/t/', '').split('/').filter(Boolean); + return parts[0] ? parts[0].trim() : null; + } + + function isCurrentThreadExplicitlyLocked(threadId) { + if (!threadId) return false; + const cleanId = String(threadId).toLowerCase().trim(); + if (lockedChatIds.has(cleanId)) return true; + const mappedUser = threadUsernameMap.get(cleanId); + if (mappedUser && lockedChatIds.has(mappedUser)) return true; + for (const lockedId of lockedChatIds) { + if (window.location.href.toLowerCase().includes(lockedId)) return true; + } + return false; + } + + function extractThreadParticipants() { + const currentThreadId = extractCurrentThreadId(); + if (!currentThreadId) return null; + + let username = ''; + let displayName = ''; + + // 1. Inspect document.title + const docTitle = document.title || ''; + const titleMatch = docTitle.match(/@([a-zA-Z0-9_\.]+)/); + if (titleMatch && titleMatch[1]) { + username = titleMatch[1].trim(); + } else if (docTitle.includes('โ€ข')) { + const candidate = docTitle.split('โ€ข')[0].trim(); + if (candidate && !['direct', 'messages', 'instagram'].includes(candidate.toLowerCase())) { + displayName = candidate; + } + } + + // 2. Inspect header avatar image alt text + if (!username) { + const headerImgs = document.querySelectorAll('header img[alt], [role="banner"] img[alt], [role="main"] header img[alt]'); + for (const img of headerImgs) { + const alt = img.getAttribute('alt') || ''; + const m = alt.match(/(.+?)'s profile picture/i) || alt.match(/profile picture of (.+)/i); + if (m && m[1]) { + username = m[1].trim().replace(/^@/, ''); + break; + } + } + } + + // 3. Instagram header profile link inspection + if (!username) { + const profileLinks = document.querySelectorAll( + 'header a[aria-label*="profile page of" i], [role="banner"] a[aria-label*="profile page of" i], ' + + '[role="main"] header a[aria-label*="profile page of" i], a[aria-label*="Open the profile page of" i], ' + + 'header a[href^="/"], [role="banner"] a[href^="/"], [role="main"] header a[href^="/"]' + ); + + for (const link of profileLinks) { + const aria = link.getAttribute('aria-label') || ''; + const matchAria = aria.match(/profile page of (.+)/i); + if (matchAria && matchAria[1]) { + username = matchAria[1].trim().replace(/^@/, ''); + break; + } + const href = link.getAttribute('href') || ''; + const cleanHref = href.replace(/^https?:\/\/[^\/]+/, ''); + const matchHref = cleanHref.match(/^\/([a-zA-Z0-9_\.]+)\/?(?:\?.*)?$/); + if (matchHref && matchHref[1]) { + const candidate = matchHref[1].trim(); + const ignored = ['direct', 'explore', 'reels', 'reel', 'stories', 'home', 'accounts', 'p', 'tv']; + if (!ignored.includes(candidate.toLowerCase())) { + username = candidate; + break; + } + } + } + } + + // 4. Header heading / title elements + const headingEl = document.querySelector( + 'header [role="heading"], [role="banner"] [role="heading"], ' + + 'header h1, header h2, header h3, [role="banner"] h1, [role="banner"] h2, ' + + 'header a span, [role="banner"] a span' + ); + if (headingEl) { + const hText = headingEl.textContent.trim().replace(/^@/, ''); + if (!displayName) displayName = hText; + if (!username && hText && !hText.includes(' ') && hText.length < 32) { + username = hText; + } + } + + // 5. In-page bio banner at top of message scroller (View profile button) + if (!username) { + const viewProfileLink = document.querySelector('a[href^="/"][role="link"]:not([href*="/direct/"])'); + if (viewProfileLink && viewProfileLink.textContent.toLowerCase().includes('profile')) { + const href = (viewProfileLink.getAttribute('href') || '').replace(/^https?:\/\/[^\/]+/, ''); + const m = href.match(/^\/([a-zA-Z0-9_\.]+)\/?/); + if (m && m[1]) { + username = m[1].trim(); + } + } + } + + const cleanUser = username ? username.toLowerCase().trim().replace(/^@/, '') : ''; + const effectiveUser = cleanUser || (displayName ? displayName.toLowerCase().trim().replace(/^@/, '') : ''); + + if (effectiveUser) { + threadUsernameMap.set(currentThreadId, effectiveUser); + threadUsernameMap.set(effectiveUser, currentThreadId); + postToNative({ + action: 'threadUsernameMapped', + threadId: currentThreadId, + username: effectiveUser, + usernames: [effectiveUser], + displayName: displayName || effectiveUser + }); + window.__fgActiveThread = { threadId: currentThreadId, username: effectiveUser, displayName: displayName || effectiveUser }; + return { username: effectiveUser, displayName: displayName || effectiveUser }; + } + return null; + } + window.__fgGetThreadParticipant = extractThreadParticipants; + + function isCurrentChatLocked() { + const path = window.location.pathname.toLowerCase(); + if (!path.startsWith('/direct')) return false; + if (chatLockMode === 'off') return false; + if (unlockedThreads.has('__all__')) return false; + + const currentThreadId = extractCurrentThreadId(); + if (currentThreadId) { + if (unlockedThreads.has(currentThreadId)) return false; + const mappedUser = threadUsernameMap.get(currentThreadId); + if (mappedUser && unlockedThreads.has(mappedUser)) return false; + + if (chatLockMode === 'whole_dm' || chatLockAll) return true; + if (isCurrentThreadExplicitlyLocked(currentThreadId)) return true; + + // Search header text as additional safeguard + const header = document.querySelector('header, [role="banner"], [role="main"] header'); + if (header) { + const headerText = header.textContent.toLowerCase(); + for (const lockedId of lockedChatIds) { + if (headerText.includes(lockedId)) { + lockedChatIds.add(currentThreadId); + threadUsernameMap.set(currentThreadId, lockedId); + postToNative({ action: 'threadUsernameMapped', threadId: currentThreadId, usernames: [lockedId], isLocked: true }); + return true; + } + } + } + return false; + } + + if ((chatLockMode === 'whole_dm' || chatLockAll) && (path === '/direct' || path === '/direct/' || path.startsWith('/direct/inbox'))) { + return !unlockedThreads.has('__all__'); + } + + return false; + } + + function applyPrivacyVeil() { + let veil = document.getElementById('focusgram-chat-privacy-veil'); + if (!veil) { + veil = document.createElement('div'); + veil.id = 'focusgram-chat-privacy-veil'; + veil.style.cssText = 'position:fixed!important;top:0!important;left:0!important;width:100vw!important;height:100vh!important;background:#000000!important;z-index:2147483647!important;pointer-events:all!important;display:block!important;'; + (document.body || document.documentElement).appendChild(veil); + } + veil.style.display = 'block'; + } + window.__fgApplyPrivacyVeil = applyPrivacyVeil; + + function removePrivacyVeil() { + const veil = document.getElementById('focusgram-chat-privacy-veil'); + if (veil) { + veil.style.display = 'none'; + } + } + window.__fgRemovePrivacyVeil = removePrivacyVeil; + + function evaluateChatLockState() { + if (isCurrentChatLocked()) { + try { + document.body?.setAttribute('data-fg-chat-locked', 'true'); + document.documentElement?.setAttribute('data-fg-chat-locked', 'true'); + } catch (_) {} + applyPrivacyVeil(); + } else { + try { + document.body?.removeAttribute('data-fg-chat-locked'); + document.documentElement?.removeAttribute('data-fg-chat-locked'); + } catch (_) {} + removePrivacyVeil(); + } + } + + // Capture-phase link click interception for instant pre-render black cover & blocking server queries + document.addEventListener('click', (e) => { + if (chatLockMode === 'off') return; + const link = e.target.closest('a[href*="/direct/t/"]'); + if (!link) return; + const href = (link.getAttribute('href') || '').toLowerCase(); + const match = href.match(/\/direct\/t\/([^\/\?]+)/); + const targetThreadId = match ? match[1].trim() : ''; + if (!targetThreadId) return; + + let shouldLock = (chatLockMode === 'whole_dm' || chatLockAll); + const mapped = threadUsernameMap.get(targetThreadId); + if (!shouldLock) { + if (lockedChatIds.has(targetThreadId)) shouldLock = true; + if (mapped && lockedChatIds.has(mapped)) shouldLock = true; + if (!shouldLock) { + const row = link.closest('[role="listitem"], [role="button"], li') || link; + const rowText = row.textContent.toLowerCase(); + for (const lockedId of lockedChatIds) { + if (rowText.includes(lockedId) || href.includes(lockedId)) { + shouldLock = true; + lockedChatIds.add(targetThreadId); + break; + } + } + } + } + + const isUnlocked = unlockedThreads.has('__all__') || + unlockedThreads.has(targetThreadId) || + (mapped && unlockedThreads.has(mapped)); + + if (shouldLock && !isUnlocked) { + // Immediately BLOCK the browser and React router from querying the server or rendering the locked chat! + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); + + applyPrivacyVeil(); + + const mappedUser = mapped || ''; + postToNative({ + action: 'requestUnlockChat', + threadId: targetThreadId, + username: mappedUser, + targetUrl: link.href || ('https://www.instagram.com/direct/t/' + targetThreadId + '/') + }); + } + }, true); + + function updateChatMaskCSS() { + let style = document.getElementById('focusgram-chat-mask-style'); + if (!style) { + style = document.createElement('style'); + style.id = 'focusgram-chat-mask-style'; + (document.head || document.documentElement).appendChild(style); + } + + const css = ` + /* FocusGram Chat Lock Veil */ + body[data-fg-chat-locked="true"] [role="list"] [role="row"], + body[data-fg-chat-locked="true"] div[dir="auto"], + body[data-fg-chat-locked="true"] [data-message-id] { + filter: blur(14px) !important; + user-select: none !important; + pointer-events: none !important; + } + `; + style.textContent = css; + } + + function maskInboxChatPreviews() { + updateChatMaskCSS(); + + const path = window.location.pathname.toLowerCase(); + if (!path.startsWith('/direct')) return; + + const isLockOff = (chatLockMode === 'off'); + + const chatLinks = document.querySelectorAll('a[href*="/direct/t/"]'); + for (const link of chatLinks) { + const href = (link.getAttribute('href') || '').toLowerCase(); + const match = href.match(/\/direct\/t\/([^\/\?]+)/); + const threadId = match ? match[1].trim() : ''; + if (!threadId) continue; + + const rowContainer = link.closest('[role="listitem"], [role="button"], li') || link; + + // Strategy A: Avatar image alt inspection + let detectedUser = ''; + let displayName = ''; + const avatarImg = rowContainer.querySelector('img[alt]'); + if (avatarImg) { + const alt = (avatarImg.getAttribute('alt') || '').trim(); + const m = alt.match(/(.+?)'s profile picture/i) || alt.match(/profile picture of (.+)/i); + if (m && m[1]) { + detectedUser = m[1].trim().replace(/^@/, '').toLowerCase(); + displayName = m[1].trim(); + } + } + + // Strategy B: TreeWalker text node for title element + const walker = document.createTreeWalker( + rowContainer, + NodeFilter.SHOW_TEXT, + { + acceptNode: function(node) { + const val = (node.nodeValue || '').trim(); + if (!val || val === '๐Ÿ”’' || val === 'โ€ข' || val === 'ยท') { + return NodeFilter.FILTER_REJECT; + } + return NodeFilter.FILTER_ACCEPT; + } + } + ); + + let candidateTitleEl = null; + const firstNode = walker.nextNode(); + if (firstNode) { + candidateTitleEl = firstNode.parentElement; + if (!detectedUser) { + const txt = (firstNode.nodeValue || '').trim(); + detectedUser = txt.replace(/^@/, '').trim().toLowerCase(); + displayName = txt; + } + } + + if (detectedUser && !threadUsernameMap.has(threadId)) { + threadUsernameMap.set(threadId, detectedUser); + threadUsernameMap.set(detectedUser, threadId); + postToNative({ + action: 'threadUsernameMapped', + threadId: threadId, + username: detectedUser, + usernames: [detectedUser], + displayName: displayName || detectedUser + }); + } + + let isLocked = false; + if (!isLockOff) { + if (chatLockMode === 'whole_dm' || chatLockAll) { + isLocked = !unlockedThreads.has('__all__'); + } else { + if (unlockedThreads.has(threadId)) { + isLocked = false; + } else { + if (lockedChatIds.has(threadId)) isLocked = true; + const mappedUser = threadUsernameMap.get(threadId); + if (mappedUser && lockedChatIds.has(mappedUser)) isLocked = true; + if (detectedUser && lockedChatIds.has(detectedUser)) isLocked = true; + if (!isLocked) { + const rowText = rowContainer.textContent.toLowerCase(); + for (const lockedId of lockedChatIds) { + if (rowText.includes(lockedId) || href.includes(lockedId)) { + isLocked = true; + lockedChatIds.add(threadId); + break; + } + } + } + if (mappedUser && unlockedThreads.has(mappedUser)) isLocked = false; + if (detectedUser && unlockedThreads.has(detectedUser)) isLocked = false; + } + } + } + + // Clean up any legacy preview masking classes or attributes + const legacyMasked = rowContainer.querySelectorAll('.fg-masked-snippet-text, [data-fg-mask-preview]'); + for (const el of legacyMasked) { + el.classList.remove('fg-masked-snippet-text'); + el.removeAttribute('data-fg-mask-preview'); + } + + if (isLocked) { + link.setAttribute('data-fg-locked-chat', 'true'); + rowContainer.setAttribute('data-fg-locked-chat', 'true'); + + const titleTarget = candidateTitleEl || rowContainer.querySelector('[role="heading"], h2, h3, span'); + if (titleTarget && !rowContainer.querySelector('.fg-chat-lock-badge')) { + const badge = document.createElement('span'); + badge.className = 'fg-chat-lock-badge'; + badge.style.cssText = 'margin-left: 6px; font-size: 11px; opacity: 0.85; vertical-align: middle; display: inline-block;'; + badge.textContent = '๐Ÿ”’'; + titleTarget.appendChild(badge); + } + } else { + link.removeAttribute('data-fg-locked-chat'); + rowContainer.removeAttribute('data-fg-locked-chat'); + const badge = rowContainer.querySelector('.fg-chat-lock-badge'); + if (badge) badge.remove(); + } + } + } + + // Attach dynamic MutationObserver on direct messaging container to ensure previews are masked in real time + if (!window.__fgInboxObserverInstalled) { + window.__fgInboxObserverInstalled = true; + const inboxObserver = new MutationObserver(() => { + const path = window.location.pathname.toLowerCase(); + if (path.startsWith('/direct')) { + maskInboxChatPreviews(); + } + }); + inboxObserver.observe(document.body || document.documentElement, { + childList: true, + subtree: true + }); + } + function checkStateAndNotify() { + evaluateChatLockState(); + extractThreadParticipants(); + maskInboxChatPreviews(); + const currentUrl = window.location.href; if (currentUrl !== lastReportedUrl) { lastReportedUrl = currentUrl; @@ -2328,6 +2929,9 @@ } window.addEventListener('focusgram:urlchange', () => { + lastInputFocused = false; + postToNative({ action: 'inputFocused', focused: false }); + postToNative({ action: 'bioInputFocused', focused: false }); checkStateAndNotify(); setTimeout(checkStateAndNotify, 100); setTimeout(checkStateAndNotify, 300); @@ -2335,6 +2939,9 @@ }); window.addEventListener('popstate', () => { + lastInputFocused = false; + postToNative({ action: 'inputFocused', focused: false }); + postToNative({ action: 'bioInputFocused', focused: false }); checkStateAndNotify(); setTimeout(checkStateAndNotify, 100); setTimeout(checkStateAndNotify, 300); @@ -2342,6 +2949,9 @@ }); window.addEventListener('hashchange', () => { + lastInputFocused = false; + postToNative({ action: 'inputFocused', focused: false }); + postToNative({ action: 'bioInputFocused', focused: false }); checkStateAndNotify(); setTimeout(checkStateAndNotify, 100); hideNav(); @@ -2849,6 +3459,13 @@ } updateGuardrailsCSS(); syncGhostSettings(); + syncChatLockSettings(msg.settings); + return; + } else if (msg.action === 'unlockChat') { + handleUnlockChat(msg.threadId, msg.all); + return; + } else if (msg.action === 'lockChat') { + handleLockChat(msg.threadId); return; } else if (msg.action === 'navigateSpa' && msg.path) { performNavClick(msg.path); @@ -3038,6 +3655,7 @@ } updateGuardrailsCSS(); syncGhostSettings(); + syncChatLockSettings(response.settings); } }); } @@ -3139,5 +3757,553 @@ } } catch (_) {} + /* ========================================================================== + 8. LIVE BIO FONT STYLIST (KEYBOARD ACCESSORY BAR & REAL-TIME INPUT) + ========================================================================== */ + const BIO_FONT_MAPS = { + normal: null, + bold: { u: 0x1D400, l: 0x1D41A, d: 0x1D7CE }, // Mathematical Bold (Zero gaps) + sans: { u: 0x1D5D4, l: 0x1D5EE, d: 0x1D7EC }, // Sans-Serif Bold (Zero gaps) + sans_italic: { u: 0x1D608, l: 0x1D622, d: null }, // Sans-Serif Italic (Zero gaps) + mono: { u: 0x1D670, l: 0x1D68A, d: 0x1D7F6 }, // Monospace (Zero gaps) + gothic: { u: 0x1D56C, l: 0x1D586, d: null }, // Bold Fraktur/Gothic (Zero gaps) + script: { u: 0x1D4D0, l: 0x1D4EA, d: null } // Bold Script/Cursive (Zero gaps) + }; + + let activeBioStyle = 'bold'; + let bioToolbarEl = null; + let bioCounterEl = null; + let activeBioTarget = null; + + function normalizeChar(char) { + if (!char) return ''; + const cp = char.codePointAt(0); + for (const [key, map] of Object.entries(BIO_FONT_MAPS)) { + if (!map) continue; + if (cp >= map.u && cp <= map.u + 25) { + return String.fromCharCode(65 + (cp - map.u)); + } + if (cp >= map.l && cp <= map.l + 25) { + return String.fromCharCode(97 + (cp - map.l)); + } + if (map.d && cp >= map.d && cp <= map.d + 9) { + return String.fromCharCode(48 + (cp - map.d)); + } + } + return char; + } + + function convertCharToStyle(char, styleKey) { + const map = BIO_FONT_MAPS[styleKey]; + if (!map || styleKey === 'normal') return normalizeChar(char); + const norm = normalizeChar(char); + const cp = norm.codePointAt(0); + if (cp >= 65 && cp <= 90) { // A-Z + return String.fromCodePoint(map.u + (cp - 65)); + } + if (cp >= 97 && cp <= 122) { // a-z + return String.fromCodePoint(map.l + (cp - 97)); + } + if (map.d && cp >= 48 && cp <= 57) { // 0-9 + return String.fromCodePoint(map.d + (cp - 48)); + } + return norm; + } + + function convertStringToStyle(text, styleKey) { + if (!text) return ''; + return Array.from(text).map(ch => convertCharToStyle(ch, styleKey)).join(''); + } + + function isBioTarget(el) { + if (!el) return false; + if (el.id === 'pepBio') return true; + const name = (el.name || '').toLowerCase(); + const id = (el.id || '').toLowerCase(); + const placeholder = (el.placeholder || '').toLowerCase(); + const aria = (el.getAttribute('aria-label') || '').toLowerCase(); + if (name === 'biography' || name.includes('bio') || id.includes('bio') || placeholder.includes('bio') || aria.includes('bio')) return true; + const path = (window.location.pathname || '').toLowerCase(); + if (path.includes('/accounts/edit') && (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT')) return true; + return false; + } + + function updateBioCharCounter() { + if (!bioCounterEl || !activeBioTarget) return; + const text = activeBioTarget.value || activeBioTarget.textContent || ''; + const codePoints = Array.from(text).length; + const utf16Length = text.length; + + bioCounterEl.textContent = `${codePoints} / 150`; + if (codePoints > 140 || utf16Length > 140) { + bioCounterEl.style.color = '#ef4444'; + } else if (codePoints > 120) { + bioCounterEl.style.color = '#f59e0b'; + } else { + bioCounterEl.style.color = '#8e8e8e'; + } + } + + function updateBioToolbarPosition() { + if (!bioToolbarEl) return; + if (window.visualViewport) { + const kbHeight = window.innerHeight - (window.visualViewport.offsetTop + window.visualViewport.height); + bioToolbarEl.style.bottom = Math.max(0, Math.round(kbHeight)) + 'px'; + } else { + bioToolbarEl.style.bottom = '0px'; + } + } + + function createBioFontToolbar() { + if (document.getElementById('fg-bio-font-toolbar')) { + return document.getElementById('fg-bio-font-toolbar'); + } + + const toolbar = document.createElement('div'); + toolbar.id = 'fg-bio-font-toolbar'; + toolbar.style.cssText = ` + position: fixed !important; + bottom: 0 !important; + left: 0 !important; + right: 0 !important; + z-index: 2147483647 !important; + background: rgba(18, 18, 18, 0.96) !important; + backdrop-filter: blur(24px) !important; + -webkit-backdrop-filter: blur(24px) !important; + border-top: 1px solid rgba(255, 255, 255, 0.15) !important; + padding: 8px 12px !important; + display: none !important; + align-items: center !important; + justify-content: space-between !important; + gap: 8px !important; + box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.7) !important; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; + user-select: none !important; + -webkit-user-select: none !important; + transition: bottom 0.15s ease-out !important; + `; + + const chipsScroll = document.createElement('div'); + chipsScroll.style.cssText = ` + display: flex !important; + align-items: center !important; + gap: 6px !important; + overflow-x: auto !important; + scrollbar-width: none !important; + -webkit-overflow-scrolling: touch !important; + flex: 1 !important; + padding: 2px 0 !important; + `; + + const STYLES = [ + { id: 'normal', label: 'Normal' }, + { id: 'bold', label: 'Bold' }, + { id: 'sans', label: 'Sans' }, + { id: 'sans_italic', label: 'Italic' }, + { id: 'mono', label: 'Mono' }, + { id: 'gothic', label: 'Gothic' }, + { id: 'script', label: 'Script' } + ]; + + STYLES.forEach(style => { + const chip = document.createElement('button'); + chip.type = 'button'; + chip.className = 'fg-font-chip'; + chip.dataset.styleId = style.id; + chip.textContent = style.label; + const isSelected = style.id === activeBioStyle; + chip.style.cssText = ` + padding: 6px 14px !important; + border-radius: 16px !important; + border: 1px solid ${isSelected ? '#ffffff' : 'rgba(255, 255, 255, 0.15)'} !important; + background: ${isSelected ? '#ffffff' : '#262626'} !important; + color: ${isSelected ? '#000000' : '#d1d5db'} !important; + font-size: 13px !important; + font-weight: ${isSelected ? '600' : '500'} !important; + white-space: nowrap !important; + cursor: pointer !important; + outline: none !important; + transition: background 0.15s ease, color 0.15s ease !important; + `; + + chip.addEventListener('click', (e) => { + e.preventDefault(); + setBioActiveStyle(style.id); + }); + + chipsScroll.appendChild(chip); + }); + + const counter = document.createElement('span'); + counter.id = 'fg-bio-counter'; + counter.style.cssText = ` + font-size: 11px !important; + font-weight: 600 !important; + color: #8e8e8e !important; + white-space: nowrap !important; + padding: 4px 8px !important; + border-radius: 12px !important; + background: rgba(255, 255, 255, 0.05) !important; + border: 1px solid rgba(255, 255, 255, 0.08) !important; + `; + counter.textContent = '0 / 150'; + + toolbar.appendChild(chipsScroll); + toolbar.appendChild(counter); + (document.body || document.documentElement).appendChild(toolbar); + + bioToolbarEl = toolbar; + bioCounterEl = counter; + return toolbar; + } + + function setBioActiveStyle(styleId) { + activeBioStyle = styleId; + if (bioToolbarEl) { + bioToolbarEl.querySelectorAll('.fg-font-chip').forEach(c => { + const isActive = c.dataset.styleId === activeBioStyle; + c.style.border = `1px solid ${isActive ? '#ffffff' : 'rgba(255, 255, 255, 0.15)'}`; + c.style.background = isActive ? '#ffffff' : '#262626'; + c.style.color = isActive ? '#000000' : '#d1d5db'; + c.style.fontWeight = isActive ? '600' : '500'; + }); + } + + const target = activeBioTarget || document.getElementById('pepBio') || document.querySelector('textarea[aria-label="Bio"]'); + if (target) { + const val = target.value || ''; + if (val && target.selectionStart !== undefined && target.selectionEnd !== undefined && target.selectionStart !== target.selectionEnd) { + const start = target.selectionStart; + const end = target.selectionEnd; + const before = val.substring(0, start); + const selectedText = val.substring(start, end); + const after = val.substring(end); + const converted = convertStringToStyle(selectedText, activeBioStyle); + try { + const proto = window.HTMLTextAreaElement ? window.HTMLTextAreaElement.prototype : Object.getPrototypeOf(target); + const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set; + if (setter) setter.call(target, before + converted + after); + else target.value = before + converted + after; + target.dispatchEvent(new Event('input', { bubbles: true })); + } catch (_) { + target.value = before + converted + after; + } + target.setSelectionRange(start, start + converted.length); + } + // If no text selected, do NOT alter existing text! + updateBioCharCounter(); + } + } + + window.__fgSetBioStyle = setBioActiveStyle; + + function showBioFontToolbar(target) { + activeBioTarget = target; + createBioFontToolbar(); + if (bioToolbarEl) { + updateBioToolbarPosition(); + bioToolbarEl.style.display = 'flex'; + updateBioCharCounter(); + } + } + + function hideBioFontToolbar() { + if (bioToolbarEl) { + bioToolbarEl.style.display = 'none'; + } + } + + // Intercept keystrokes on document capture level for instant Unicode glyph conversion + document.addEventListener('beforeinput', (e) => { + if (!activeBioTarget || activeBioStyle === 'normal') return; + if (e.data && e.inputType === 'insertText') { + e.preventDefault(); + const converted = convertStringToStyle(e.data, activeBioStyle); + document.execCommand('insertText', false, converted); + updateBioCharCounter(); + } + }, true); + + document.addEventListener('input', (e) => { + if (activeBioTarget && (e.target === activeBioTarget || isBioTarget(e.target))) { + updateBioCharCounter(); + } + }, true); + + // Dynamic focusin detection across document + document.addEventListener('focusin', (e) => { + if (isBioTarget(e.target)) { + showBioFontToolbar(e.target); + postToNative({ action: 'bioInputFocused', focused: true }); + } + }, true); + + document.addEventListener('focusout', () => { + setTimeout(() => { + const active = document.activeElement; + if (!isBioTarget(active) && (!bioToolbarEl || !bioToolbarEl.contains(active))) { + hideBioFontToolbar(); + postToNative({ action: 'bioInputFocused', focused: false }); + } + }, 250); + }, true); + + if (window.visualViewport) { + window.visualViewport.addEventListener('resize', updateBioToolbarPosition); + window.visualViewport.addEventListener('scroll', updateBioToolbarPosition); + } + + // Listen for font style changes from background or native host + if (typeof browser !== 'undefined' && browser.runtime && browser.runtime.onMessage) { + browser.runtime.onMessage.addListener((msg) => { + if (msg.action === 'setBioStyle' && msg.style) { + setBioActiveStyle(msg.style); + } + }); + } + + /* ========================================================================== + 9. NETWORK-TRIGGERED STORY VIEWER SEARCH + - Directly displays the search bar when the /list_reel_media_viewer/ + network request is sent or received. + ========================================================================== */ + let storySearchCardEl = null; + let storyViewersData = []; + + function findViewersDialog() { + const dialogs = document.querySelectorAll('div[aria-modal="true"][role="dialog"], div[role="dialog"]'); + for (const d of dialogs) { + const headings = Array.from(d.querySelectorAll('h2, [role="heading"], div')); + const h2 = headings.find(el => el.textContent.trim().toLowerCase() === 'viewers' && el.children.length === 0); + if (h2) { + const headerRow = h2.parentElement; + const scrollContainer = d.querySelector('div[style*="overflow"]') || + d.querySelector('div[style*="height"]') || + (headerRow ? headerRow.nextElementSibling : null); + return { dialog: d, header: headerRow, scrollContainer: scrollContainer, h2: h2 }; + } + } + return null; + } + + function ensureStorySearchCard() { + if (document.getElementById('fg-story-search-card')) { + return document.getElementById('fg-story-search-card'); + } + + const card = document.createElement('div'); + card.id = 'fg-story-search-card'; + card.style.cssText = ` + margin: 6px 16px 10px 16px !important; + padding: 0 12px !important; + height: 38px !important; + background: #262626 !important; + border: 1px solid rgba(255, 255, 255, 0.12) !important; + border-radius: 8px !important; + display: flex !important; + align-items: center !important; + gap: 10px !important; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; + color: #FAFAFA !important; + box-sizing: border-box !important; + flex-shrink: 0 !important; + `; + + const searchIcon = document.createElement('span'); + searchIcon.style.cssText = 'display: flex; align-items: center; color: #8e8e8e;'; + searchIcon.innerHTML = ``; + + const searchInput = document.createElement('input'); + searchInput.id = 'fg-story-search-input'; + searchInput.type = 'text'; + searchInput.placeholder = 'Search viewers'; + searchInput.autocomplete = 'off'; + searchInput.style.cssText = ` + flex: 1 !important; + background: transparent !important; + border: none !important; + color: #FAFAFA !important; + font-size: 14px !important; + outline: none !important; + padding: 0 !important; + height: 100% !important; + font-family: inherit !important; + `; + + const clearBtn = document.createElement('button'); + clearBtn.type = 'button'; + clearBtn.textContent = 'โœ•'; + clearBtn.style.cssText = ` + background: transparent !important; + border: none !important; + color: #8e8e8e !important; + font-size: 13px !important; + cursor: pointer !important; + padding: 4px !important; + display: none !important; + line-height: 1 !important; + `; + + clearBtn.addEventListener('click', (e) => { + e.preventDefault(); + searchInput.value = ''; + clearBtn.style.display = 'none'; + filterViewers(''); + searchInput.focus(); + }); + + searchInput.addEventListener('input', () => { + const val = searchInput.value; + clearBtn.style.display = val.length > 0 ? 'block' : 'none'; + filterViewers(val.trim().toLowerCase()); + }); + + card.appendChild(searchIcon); + card.appendChild(searchInput); + card.appendChild(clearBtn); + + const info = findViewersDialog(); + if (info && info.header) { + info.header.after(card); + } + + storySearchCardEl = card; + return card; + } + + function filterViewers(query) { + const info = findViewersDialog(); + if (!info || !info.dialog) return; + + const scrollContainer = info.scrollContainer || + info.dialog.querySelector('div[style*="overflow"]') || + info.dialog.querySelector('div[style*="height"]') || + info.dialog; + + const rows = scrollContainer.querySelectorAll('.x1qnrgzn, div[style*="display: flex"] > div:has(a[href^="/"]), div[style*="padding"] > div:has(a[href^="/"])'); + let matchedCount = 0; + let totalCount = 0; + + rows.forEach(row => { + if (row.id === 'fg-story-search-card' || row.contains(document.getElementById('fg-story-search-card'))) return; + const links = row.querySelectorAll('a[href^="/"]'); + if (links.length === 0) return; + + totalCount++; + if (!query) { + row.style.display = ''; + matchedCount++; + return; + } + + const text = (row.textContent || '').toLowerCase(); + let matched = text.includes(query); + for (let i = 0; i < links.length; i++) { + const href = (links[i].getAttribute('href') || '').toLowerCase().replace(/\//g, ''); + if (href.includes(query)) { + matched = true; + break; + } + } + + row.style.display = matched ? '' : 'none'; + if (matched) matchedCount++; + }); + + let noResultsEl = scrollContainer.querySelector('#fg-no-viewer-results'); + if (query && matchedCount === 0 && totalCount > 0) { + if (!noResultsEl) { + noResultsEl = document.createElement('div'); + noResultsEl.id = 'fg-no-viewer-results'; + noResultsEl.style.cssText = 'padding: 24px; text-align: center; color: #8e8e8e; font-size: 14px;'; + noResultsEl.textContent = 'No viewers found'; + scrollContainer.appendChild(noResultsEl); + } + noResultsEl.style.display = 'block'; + } else if (noResultsEl) { + noResultsEl.style.display = 'none'; + } + } + + function checkAndMountStorySearch() { + const info = findViewersDialog(); + if (!info || !info.header) { + const existing = document.getElementById('fg-story-search-card'); + if (existing && !document.querySelector('div[aria-modal="true"][role="dialog"]')) { + existing.remove(); + storySearchCardEl = null; + } + return; + } + + if (info.dialog.querySelector('#fg-story-search-card')) { + return; + } + + ensureStorySearchCard(); + } + + function handleStoryViewersDetected(detail) { + if (!detail) return; + checkAndMountStorySearch(); + + if (detail.phase === 'ready' && detail.data) { + const data = detail.data; + const users = data.users || []; + const viewers = data.viewers || []; + const userMap = new Map(); + users.forEach(u => { + const pk = String(u.pk || u.id || ''); + if (pk) userMap.set(pk, { username: u.username || '', fullName: u.full_name || '' }); + }); + viewers.forEach(v => { + const u = v.user || v; + const pk = String(u.pk || u.id || ''); + if (pk) userMap.set(pk, { username: u.username || '', fullName: u.full_name || '' }); + }); + storyViewersData = Array.from(userMap.values()); + const input = document.getElementById('fg-story-search-input'); + if (input && input.value.trim()) { + filterViewers(input.value.trim().toLowerCase()); + } + } + } + + // Listen to main-world fetch interceptor custom events + window.addEventListener('focusgram:story-viewers-detected', (e) => { + handleStoryViewersDetected(e.detail); + }); + document.addEventListener('focusgram:story-viewers-detected', (e) => { + handleStoryViewersDetected(e.detail); + }); + + // Listen to WebExtension background script messages + if (typeof browser !== 'undefined' && browser.runtime && browser.runtime.onMessage) { + browser.runtime.onMessage.addListener((msg) => { + if (msg.action === 'storyViewersDetected') { + handleStoryViewersDetected(msg); + } + }); + } + + // Continuous autonomous observer for Viewers modal + const viewersObserver = new MutationObserver(() => { + checkAndMountStorySearch(); + }); + viewersObserver.observe(document.documentElement, { childList: true, subtree: true }); + setInterval(checkAndMountStorySearch, 400); + + // Dismiss search bar on route change away from stories + window.addEventListener('focusgram:urlchange', (e) => { + const url = (e.detail || window.location.href).toLowerCase(); + if (!url.includes('/stories/')) { + if (storySearchCardEl) { + storySearchCardEl.remove(); + storySearchCardEl = null; + } + } + }); + })(); + diff --git a/Ported/app/src/main/assets/scripts/fetch_interceptor.js b/Ported/app/src/main/assets/scripts/fetch_interceptor.js index 18607fc..91d1ec1 100644 --- a/Ported/app/src/main/assets/scripts/fetch_interceptor.js +++ b/Ported/app/src/main/assets/scripts/fetch_interceptor.js @@ -15,6 +15,7 @@ function isAuthPage() { try { var path = (window.location.pathname || '').toLowerCase(); + if (path.includes('/accounts/edit')) return false; if (path.startsWith('/accounts') || path.startsWith('/login') || path.startsWith('/signup')) return true; var c = document.cookie || ''; if (!c.includes('sessionid=') && !c.includes('ds_user_id=')) return true; @@ -231,6 +232,271 @@ } } + let localChatLockMode = 'individual'; + let localChatLockAll = false; + let localLockedChatIds = []; + let localUnlockedThreads = []; + let localThreadUsernameMap = {}; + + function handleChatLockSync(detail) { + if (!detail) return; + if (typeof detail.chatLockMode !== 'undefined') localChatLockMode = String(detail.chatLockMode).toLowerCase(); + if (typeof detail.chatLockAll !== 'undefined') localChatLockAll = !!detail.chatLockAll; + if (Array.isArray(detail.lockedChatIds)) localLockedChatIds = detail.lockedChatIds; + if (Array.isArray(detail.unlockedThreads)) localUnlockedThreads = detail.unlockedThreads; + if (detail.threadUsernameMap && typeof detail.threadUsernameMap === 'object') localThreadUsernameMap = detail.threadUsernameMap; + } + + window.addEventListener('focusgram:chat-lock-sync', (e) => handleChatLockSync(e.detail)); + document.addEventListener('focusgram:chat-lock-sync', (e) => handleChatLockSync(e.detail)); + + function isDirectThreadLocked(threadId, username) { + const mode = window.__fgChatLockMode || localChatLockMode || 'individual'; + if (mode === 'off') return false; + + const cleanTid = String(threadId || '').toLowerCase().trim(); + const cleanUser = String(username || '').toLowerCase().trim().replace(/^@/, ''); + + // Resolve mapped usernames/IDs from maps + const gMap = window.__fgThreadUsernameMap || localThreadUsernameMap || {}; + const mappedUser = cleanTid ? (gMap.get ? gMap.get(cleanTid) : gMap[cleanTid]) : ''; + const mappedId = cleanUser ? (gMap.get ? gMap.get(cleanUser) : gMap[cleanUser]) : ''; + + const checkInCollection = (collection, val) => { + if (!collection || !val) return false; + if (typeof collection.has === 'function') return collection.has(val); + if (Array.isArray(collection)) return collection.includes(val); + return false; + }; + + // Check if unlocked in current session + const unlockedSources = [window.__fgUnlockedThreads, localUnlockedThreads]; + for (const unl of unlockedSources) { + if (unl) { + if (checkInCollection(unl, '__all__') || + checkInCollection(unl, cleanTid) || + checkInCollection(unl, cleanUser) || + (mappedUser && checkInCollection(unl, mappedUser)) || + (mappedId && checkInCollection(unl, mappedId))) { + return false; + } + } + } + + // Whole DM lock mode + if (mode === 'whole_dm' || window.__fgChatLockAll || localChatLockAll) return true; + + // Individual chat lock check + const lockedSources = [window.__fgLockedChatIds, localLockedChatIds]; + for (const lk of lockedSources) { + if (lk) { + if (checkInCollection(lk, cleanTid) || + checkInCollection(lk, cleanUser) || + (mappedUser && checkInCollection(lk, mappedUser)) || + (mappedId && checkInCollection(lk, mappedId))) { + return true; + } + } + } + return false; + } + + function maskMessageNode(node) { + if (!node || typeof node !== 'object') return false; + let didMask = false; + if (typeof node.text_body === 'string' && node.text_body.length > 0) { + node.text_body = 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'; + didMask = true; + } + if (typeof node.text === 'string' && node.text.length > 0) { + node.text = 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'; + didMask = true; + } + if (typeof node.snippet === 'string' && node.snippet.length > 0) { + node.snippet = 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'; + didMask = true; + } + if (node.content && typeof node.content === 'object') { + if (typeof node.content.text_body === 'string' && node.content.text_body.length > 0) { + node.content.text_body = 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'; + didMask = true; + } + if (typeof node.content.text === 'string' && node.content.text.length > 0) { + node.content.text = 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'; + didMask = true; + } + if (typeof node.content.snippet === 'string' && node.content.snippet.length > 0) { + node.content.snippet = 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'; + didMask = true; + } + } + return didMask; + } + + function maskThreadMessages(thread) { + if (!thread || typeof thread !== 'object') return false; + let threadMod = false; + + // 1. slide_messages.edges[].node (HAR / GraphQL IGDThreadDetailQuery format) + if (thread.slide_messages && Array.isArray(thread.slide_messages.edges)) { + for (const edge of thread.slide_messages.edges) { + if (edge && edge.node && maskMessageNode(edge.node)) { + threadMod = true; + } + } + } + + // 2. messages.edges or messages.items or messages[] + if (thread.messages) { + if (Array.isArray(thread.messages.edges)) { + for (const edge of thread.messages.edges) { + if (edge && edge.node && maskMessageNode(edge.node)) { + threadMod = true; + } + } + } else if (Array.isArray(thread.messages.items)) { + for (const item of thread.messages.items) { + if (maskMessageNode(item)) { + threadMod = true; + } + } + } else if (Array.isArray(thread.messages)) { + for (const item of thread.messages) { + if (maskMessageNode(item)) { + threadMod = true; + } + } + } + } + + // 3. items[] + if (Array.isArray(thread.items)) { + for (const item of thread.items) { + if (maskMessageNode(item)) { + threadMod = true; + } + } + } + + // 4. last_permanent_item + if (thread.last_permanent_item && maskMessageNode(thread.last_permanent_item)) { + threadMod = true; + } + + // 5. snippet + if (typeof thread.snippet === 'string') { + thread.snippet = 'โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข'; + threadMod = true; + } + + return threadMod; + } + + function findThreadsInPayload(root) { + const threads = []; + if (!root || typeof root !== 'object') return threads; + + if (root.get_slide_thread_nullable?.as_ig_direct_thread) { + threads.push(root.get_slide_thread_nullable.as_ig_direct_thread); + } else if (root.get_slide_thread_nullable && typeof root.get_slide_thread_nullable === 'object') { + threads.push(root.get_slide_thread_nullable); + } + if (root.message_thread && typeof root.message_thread === 'object') { + threads.push(root.message_thread); + } + if (root.thread && typeof root.thread === 'object') { + threads.push(root.thread); + } + + const inbox = root.viewer?.inbox || root.inbox; + if (inbox && Array.isArray(inbox.threads)) { + for (const t of inbox.threads) { + if (t && typeof t === 'object') threads.push(t); + } + } + + if (threads.length === 0) { + for (const key of Object.keys(root)) { + const val = root[key]; + if (val && typeof val === 'object') { + if (val.slide_messages || val.as_ig_direct_thread || (val.thread_fbid && (val.items || val.messages))) { + threads.push(val.as_ig_direct_thread || val); + } + } + } + } + + return threads; + } + + function processDirectMessagesPayload(data) { + if (!data || typeof data !== 'object') return false; + + let modified = false; + const root = data.data || data; + const threads = findThreadsInPayload(root); + if (threads.length === 0) return false; + + for (const thread of threads) { + const tid = String(thread.thread_fbid || thread.id || thread.thread_id || '').toLowerCase().trim(); + const threadKey = String(thread.thread_key || '').toLowerCase().trim(); + let username = ''; + let displayName = thread.thread_title || ''; + const allUsernames = []; + + if (Array.isArray(thread.users)) { + for (const u of thread.users) { + if (u && u.username) { + const uname = String(u.username).toLowerCase().trim().replace(/^@/, ''); + if (uname) allUsernames.push(uname); + } + } + if (allUsernames.length > 0) { + username = allUsernames[0]; + if (!displayName) displayName = thread.users[0].full_name || username; + } + } + + const primaryId = tid || threadKey; + if (primaryId && (allUsernames.length > 0 || displayName)) { + window.dispatchEvent(new CustomEvent('focusgram:thread-matched', { + detail: { + threadId: primaryId, + threadKey: threadKey, + usernames: allUsernames, + displayName: displayName + } + })); + } + + let isLocked = isDirectThreadLocked(tid, username); + if (!isLocked && threadKey) isLocked = isDirectThreadLocked(threadKey, username); + if (!isLocked) { + for (const u of allUsernames) { + if (isDirectThreadLocked(tid || threadKey, u)) { + isLocked = true; + break; + } + } + } + + if (isLocked) { + // Do not mask inbox list previews + const isInboxItem = !thread.slide_messages && (thread.last_permanent_item || thread.snippet); + if (isInboxItem) { + continue; + } + if (maskThreadMessages(thread)) { + modified = true; + } + } + } + + return modified; + } + + window.__fgProcessDirectMessagesPayload = processDirectMessagesPayload; + // Override fetch in the main world const _fetch = window.fetch.bind(window); @@ -241,35 +507,83 @@ ? input.href : input?.url ?? ''; + // Story viewer request detection: immediately notify UI when request is sent and received + if (url.includes('/list_reel_media_viewer/')) { + const mediaIdMatch = url.match(/\/api\/v1\/media\/(\d+)\/list_reel_media_viewer\//); + const mediaId = mediaIdMatch ? mediaIdMatch[1] : ''; + const loadingDetail = { phase: 'loading', mediaId: mediaId, url: url }; + + // Dispatch to both window & document for maximum compatibility across script compartments + window.dispatchEvent(new CustomEvent('focusgram:story-viewers-detected', { detail: loadingDetail })); + document.dispatchEvent(new CustomEvent('focusgram:story-viewers-detected', { detail: loadingDetail })); + window.postMessage({ type: 'FOCUSGRAM_STORY_VIEWERS', detail: loadingDetail }, '*'); + handleStoryViewersDetected(loadingDetail); + + const response = await _fetch(input, init); + try { + const cloned = response.clone(); + cloned.json().then(data => { + const readyDetail = { phase: 'ready', mediaId: mediaId, url: url, data: data }; + window.dispatchEvent(new CustomEvent('focusgram:story-viewers-detected', { detail: readyDetail })); + document.dispatchEvent(new CustomEvent('focusgram:story-viewers-detected', { detail: readyDetail })); + window.postMessage({ type: 'FOCUSGRAM_STORY_VIEWERS', detail: readyDetail }, '*'); + handleStoryViewersDetected(readyDetail); + }).catch(() => {}); + } catch (_) {} + return response; + } + + // Always execute fetch const response = await _fetch(input, init); - // Only inspect GraphQL, feed, and clips endpoints - if (!url.includes('/graphql') && !url.includes('/api/v1/feed') && !url.includes('/api/v1/clips/')) { + // Only inspect GraphQL, feed, clips, and threads endpoints + if (!url.includes('/graphql') && !url.includes('/api/v1/feed') && !url.includes('/api/v1/clips/') && !url.includes('/api/v1/direct_v2/threads/')) { return response; } const config = window.__fgFilterConfig; - if (config && config.blockAds === false) { - return response; - } const cloned = response.clone(); try { const contentType = response.headers.get('content-type') || ''; - if (!contentType.includes('application/json')) { + if (!contentType.includes('json') && !contentType.includes('javascript')) { return response; } - const data = await cloned.json(); - harvestMediaFromData(data); - walkAndFilter(data); + let data; + try { + data = await cloned.json(); + } catch (_) { + try { + let text = await cloned.text(); + text = text.replace(/^for\s*\(\s*;\s*;\s*\)\s*;\s*/, ''); + data = JSON.parse(text); + } catch (e) { + return response; + } + } + harvestMediaFromData(data); + + const directModified = processDirectMessagesPayload(data); + + let adModified = false; + if (config && config.blockAds !== false) { + walkAndFilter(data); + adModified = true; + } + + if (!directModified && !adModified) { + return response; + } + + const originalContentType = response.headers.get('content-type') || 'application/json; charset=utf-8'; const newHeaders = new Headers(response.headers); // CRITICAL: Must delete content-length and content-encoding so the uncompressed // JSON body is not truncated or corrupted by the browser HTTP layer newHeaders.delete('content-length'); newHeaders.delete('content-encoding'); - newHeaders.set('content-type', 'application/json; charset=utf-8'); + newHeaders.set('content-type', originalContentType); return new Response(JSON.stringify(data), { status: response.status, @@ -287,6 +601,259 @@ configurable: true }); + // Hook XMLHttpRequest for complete coverage of background API calls + const origXHR = window.XMLHttpRequest; + if (origXHR && origXHR.prototype) { + const origOpen = origXHR.prototype.open; + const origSend = origXHR.prototype.send; + + origXHR.prototype.open = function(method, url) { + this._fgUrl = typeof url === 'string' ? url : (url ? url.toString() : ''); + return origOpen.apply(this, arguments); + }; + + origXHR.prototype.send = function() { + const xhr = this; + const url = xhr._fgUrl || ''; + if (url.includes('/graphql') || url.includes('/api/v1/direct') || url.includes('/direct/')) { + const onReady = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + try { + const cType = xhr.getResponseHeader('content-type') || ''; + if (cType.includes('json') || cType.includes('javascript')) { + let text = xhr.responseText; + if (text) { + text = text.replace(/^for\s*\(\s*;\s*;\s*\)\s*;\s*/, ''); + const data = JSON.parse(text); + if (processDirectMessagesPayload(data)) { + const modifiedText = JSON.stringify(data); + Object.defineProperty(xhr, 'responseText', { value: modifiedText, writable: true, configurable: true }); + Object.defineProperty(xhr, 'response', { value: modifiedText, writable: true, configurable: true }); + } + } + } + } catch (_) {} + } + }; + xhr.addEventListener('readystatechange', onReady, false); + } + return origSend.apply(this, arguments); + }; + } + + /* ========================================================================== + STORY VIEWER CLIENT-SIDE SEARCH ENGINE + Autonomous DOM detector + Network Interception. + Injects a native-style Instagram search bar inside the "Viewers" modal + whether opened from cached story data or network requests. + ========================================================================== */ + let storyViewersData = []; + let storySearchCardEl = null; + + function findViewersDialog() { + const dialogs = document.querySelectorAll('div[aria-modal="true"][role="dialog"], div[role="dialog"]'); + for (const d of dialogs) { + const headings = Array.from(d.querySelectorAll('h2, [role="heading"], div')); + const h2 = headings.find(el => el.textContent.trim().toLowerCase() === 'viewers' && el.children.length === 0); + if (h2) { + // h2.parentElement is the flex row containing Close button, Viewers title, and spacer + const headerRow = h2.parentElement; + const scrollContainer = d.querySelector('div[style*="overflow"]') || + d.querySelector('div[style*="height"]') || + (headerRow ? headerRow.nextElementSibling : null); + return { dialog: d, header: headerRow, scrollContainer: scrollContainer, h2: h2 }; + } + } + return null; + } + + function createStorySearchCard() { + const card = document.createElement('div'); + card.id = 'fg-story-search-card'; + card.style.cssText = ` + margin: 6px 16px 10px 16px !important; + padding: 0 10px !important; + height: 38px !important; + background: #262626 !important; + border: 1px solid rgba(255, 255, 255, 0.1) !important; + border-radius: 8px !important; + display: flex !important; + align-items: center !important; + gap: 8px !important; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; + color: #ffffff !important; + box-sizing: border-box !important; + flex-shrink: 0 !important; + `; + + const searchIcon = document.createElement('span'); + searchIcon.style.cssText = 'display: flex; align-items: center; color: #8e8e8e;'; + searchIcon.innerHTML = ``; + + const searchInput = document.createElement('input'); + searchInput.id = 'fg-story-search-input'; + searchInput.type = 'text'; + searchInput.placeholder = 'Search viewers'; + searchInput.autocomplete = 'off'; + searchInput.style.cssText = ` + flex: 1 !important; + background: transparent !important; + border: none !important; + color: #FAFAFA !important; + font-size: 14px !important; + outline: none !important; + padding: 0 !important; + height: 100% !important; + font-family: inherit !important; + `; + + const clearBtn = document.createElement('button'); + clearBtn.type = 'button'; + clearBtn.textContent = 'โœ•'; + clearBtn.style.cssText = ` + background: transparent !important; + border: none !important; + color: #8e8e8e !important; + font-size: 13px !important; + cursor: pointer !important; + padding: 4px !important; + display: none !important; + line-height: 1 !important; + `; + + clearBtn.addEventListener('click', (e) => { + e.preventDefault(); + searchInput.value = ''; + clearBtn.style.display = 'none'; + filterViewers(''); + searchInput.focus(); + }); + + searchInput.addEventListener('input', () => { + const val = searchInput.value; + clearBtn.style.display = val.length > 0 ? 'block' : 'none'; + filterViewers(val.trim().toLowerCase()); + }); + + card.appendChild(searchIcon); + card.appendChild(searchInput); + card.appendChild(clearBtn); + + return card; + } + + function filterViewers(query) { + const info = findViewersDialog(); + if (!info || !info.dialog) return; + + const scrollContainer = info.scrollContainer || + info.dialog.querySelector('div[style*="overflow"]') || + info.dialog.querySelector('div[style*="height"]') || + info.dialog; + + // Target viewer rows: .x1qnrgzn, or rows containing profile links + const rows = scrollContainer.querySelectorAll('.x1qnrgzn, div[style*="display: flex"] > div:has(a[href^="/"]), div[style*="padding"] > div:has(a[href^="/"])'); + let matchedCount = 0; + let totalCount = 0; + + rows.forEach(row => { + if (row.id === 'fg-story-search-card' || row.contains(document.getElementById('fg-story-search-card'))) return; + const links = row.querySelectorAll('a[href^="/"]'); + if (links.length === 0) return; + + totalCount++; + if (!query) { + row.style.display = ''; + matchedCount++; + return; + } + + const text = (row.textContent || '').toLowerCase(); + let matched = text.includes(query); + for (let i = 0; i < links.length; i++) { + const href = (links[i].getAttribute('href') || '').toLowerCase().replace(/\//g, ''); + if (href.includes(query)) { + matched = true; + break; + } + } + + row.style.display = matched ? '' : 'none'; + if (matched) matchedCount++; + }); + + // Handle "No results found" placeholder + let noResultsEl = scrollContainer.querySelector('#fg-no-viewer-results'); + if (query && matchedCount === 0 && totalCount > 0) { + if (!noResultsEl) { + noResultsEl = document.createElement('div'); + noResultsEl.id = 'fg-no-viewer-results'; + noResultsEl.style.cssText = 'padding: 24px; text-align: center; color: #8e8e8e; font-size: 14px;'; + noResultsEl.textContent = 'No viewers found'; + scrollContainer.appendChild(noResultsEl); + } + noResultsEl.style.display = 'block'; + } else if (noResultsEl) { + noResultsEl.style.display = 'none'; + } + } + + function checkAndMountStorySearch() { + const info = findViewersDialog(); + if (!info || !info.header) { + const existing = document.getElementById('fg-story-search-card'); + if (existing && !document.querySelector('div[aria-modal="true"][role="dialog"]')) { + existing.remove(); + storySearchCardEl = null; + } + return; + } + + if (info.dialog.querySelector('#fg-story-search-card')) { + return; + } + + const card = createStorySearchCard(); + info.header.after(card); + storySearchCardEl = card; + } + + function handleStoryViewersDetected(detail) { + if (!detail) return; + checkAndMountStorySearch(); + + if (detail.phase === 'ready' && detail.data) { + const data = detail.data; + const users = data.users || []; + const viewers = data.viewers || []; + const userMap = new Map(); + users.forEach(u => { + const pk = String(u.pk || u.id || ''); + if (pk) userMap.set(pk, { username: u.username || '', fullName: u.full_name || '' }); + }); + viewers.forEach(v => { + const u = v.user || v; + const pk = String(u.pk || u.id || ''); + if (pk) userMap.set(pk, { username: u.username || '', fullName: u.full_name || '' }); + }); + storyViewersData = Array.from(userMap.values()); + const input = document.getElementById('fg-story-search-input'); + if (input && input.value.trim()) { + filterViewers(input.value.trim().toLowerCase()); + } + } + } + + window.__fgHandleStoryViewers = handleStoryViewersDetected; + window.addEventListener('focusgram:story-viewers-detected', (e) => handleStoryViewersDetected(e.detail)); + document.addEventListener('focusgram:story-viewers-detected', (e) => handleStoryViewersDetected(e.detail)); + + // Continuous autonomous observer for Viewers modal + const viewersObserver = new MutationObserver(() => { + checkAndMountStorySearch(); + }); + viewersObserver.observe(document.documentElement, { childList: true, subtree: true }); + window.__fgSetFilterConfig = function (cfg) { if (typeof cfg === 'object' && cfg) { Object.assign(window.__fgFilterConfig, cfg); diff --git a/Ported/app/src/main/assets/scripts/native_feel.js b/Ported/app/src/main/assets/scripts/native_feel.js index 4934ee3..bd25114 100644 --- a/Ported/app/src/main/assets/scripts/native_feel.js +++ b/Ported/app/src/main/assets/scripts/native_feel.js @@ -15,6 +15,7 @@ function isAuthPage() { try { var path = (window.location.pathname || '').toLowerCase(); + if (path.includes('/accounts/edit')) return false; if (path.startsWith('/accounts') || path.startsWith('/login') || path.startsWith('/signup')) return true; var c = document.cookie || ''; if (!c.includes('sessionid=') && !c.includes('ds_user_id=')) return true; @@ -206,6 +207,327 @@ } catch (_) {} } + /* ========================================================================== + 7. LIVE BIO FONT STYLIST & REAL-TIME INPUT ENGINE + Directly mounts a dedicated styling accessory bar above textarea#pepBio, + handles bidirectional Unicode mathematical font conversion, + and transforms typing in real time. + ========================================================================== */ + const BIO_FONT_MAPS = { + normal: null, + bold: { u: 0x1D400, l: 0x1D41A, d: 0x1D7CE }, // Mathematical Bold (Zero gaps) + sans: { u: 0x1D5D4, l: 0x1D5EE, d: 0x1D7EC }, // Sans-Serif Bold (Zero gaps) + sans_italic: { u: 0x1D608, l: 0x1D622, d: null }, // Sans-Serif Italic (Zero gaps) + mono: { u: 0x1D670, l: 0x1D68A, d: 0x1D7F6 }, // Monospace (Zero gaps) + gothic: { u: 0x1D56C, l: 0x1D586, d: null }, // Bold Fraktur/Gothic (Zero gaps) + script: { u: 0x1D4D0, l: 0x1D4EA, d: null } // Bold Script/Cursive (Zero gaps) + }; + + let activeBioStyle = 'bold'; + let activeBioTarget = null; + let bioInlineBarEl = null; + + function normalizeChar(char) { + if (!char) return ''; + const cp = char.codePointAt(0); + for (const [key, map] of Object.entries(BIO_FONT_MAPS)) { + if (!map) continue; + if (cp >= map.u && cp <= map.u + 25) { + return String.fromCharCode(65 + (cp - map.u)); + } + if (cp >= map.l && cp <= map.l + 25) { + return String.fromCharCode(97 + (cp - map.l)); + } + if (map.d && cp >= map.d && cp <= map.d + 9) { + return String.fromCharCode(48 + (cp - map.d)); + } + } + return char; + } + + function convertCharToStyle(char, styleKey) { + const map = BIO_FONT_MAPS[styleKey]; + if (!map || styleKey === 'normal') return normalizeChar(char); + const norm = normalizeChar(char); + const cp = norm.codePointAt(0); + if (cp >= 65 && cp <= 90) { // A-Z + return String.fromCodePoint(map.u + (cp - 65)); + } + if (cp >= 97 && cp <= 122) { // a-z + return String.fromCodePoint(map.l + (cp - 97)); + } + if (map.d && cp >= 48 && cp <= 57) { // 0-9 + return String.fromCodePoint(map.d + (cp - 48)); + } + return norm; + } + + function convertStringToStyle(text, styleKey) { + if (!text) return ''; + return Array.from(text).map(ch => convertCharToStyle(ch, styleKey)).join(''); + } + + function isBioTarget(el) { + if (!el) return false; + if (el.id === 'pepBio') return true; + const name = (el.name || '').toLowerCase(); + const placeholder = (el.placeholder || '').toLowerCase(); + const aria = (el.getAttribute('aria-label') || '').toLowerCase(); + if (name === 'biography' || name === 'bio' || placeholder === 'bio' || aria === 'bio') return true; + const path = (window.location.pathname || '').toLowerCase(); + if (path.includes('/accounts/edit') && (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT')) return true; + return false; + } + + function updateBioCharCounter(target) { + const el = target || activeBioTarget || document.getElementById('pepBio'); + const counter = document.getElementById('fg-bio-counter'); + if (!el || !counter) return; + + const text = el.value || el.textContent || ''; + const codePoints = Array.from(text).length; + + counter.textContent = `${codePoints} / 150`; + if (codePoints > 140) { + counter.style.color = '#ef4444'; + } else if (codePoints > 120) { + counter.style.color = '#f59e0b'; + } else { + counter.style.color = '#8e8e8e'; + } + } + + function setReactInputValue(input, val) { + if (!input) return; + try { + const proto = window.HTMLTextAreaElement ? window.HTMLTextAreaElement.prototype : Object.getPrototypeOf(input); + const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set; + if (setter) { + setter.call(input, val); + } else { + input.value = val; + } + input.dispatchEvent(new Event('input', { bubbles: true })); + input.dispatchEvent(new Event('change', { bubbles: true })); + } catch (_) { + input.value = val; + } + } + + function applyBioStyleToTarget(styleId) { + activeBioStyle = styleId; + const target = activeBioTarget || document.getElementById('pepBio') || document.querySelector('textarea[aria-label="Bio"]'); + + // Update inline chip states (native Instagram Stories pill style) + document.querySelectorAll('.fg-bio-chip').forEach(c => { + const isSelected = c.dataset.styleId === activeBioStyle; + c.style.background = isSelected ? '#ffffff' : '#262626'; + c.style.borderColor = isSelected ? '#ffffff' : 'rgba(255, 255, 255, 0.15)'; + c.style.color = isSelected ? '#000000' : '#d1d5db'; + c.style.fontWeight = isSelected ? '600' : '500'; + }); + + if (!target) return; + + // Convert ONLY selected text if user made an explicit text selection + const val = target.value || ''; + if (val && target.selectionStart !== undefined && target.selectionEnd !== undefined && target.selectionStart !== target.selectionEnd) { + const start = target.selectionStart; + const end = target.selectionEnd; + const before = val.substring(0, start); + const selected = val.substring(start, end); + const after = val.substring(end); + const converted = convertStringToStyle(selected, activeBioStyle); + setReactInputValue(target, before + converted + after); + target.setSelectionRange(start, start + converted.length); + } + // If NO text is selected, do NOT alter existing text! + // activeBioStyle is set, so only characters typed afterwards will be converted. + updateBioCharCounter(target); + } + + window.__fgSetBioStyle = applyBioStyleToTarget; + + function notifyBioFocus(focused) { + try { + window.postMessage({ type: 'FOCUSGRAM_BIO_FOCUSED', focused: focused }, '*'); + document.dispatchEvent(new CustomEvent('focusgram:bio-focused', { detail: { focused: focused } })); + if (typeof browser !== 'undefined' && browser.runtime && browser.runtime.sendMessage) { + browser.runtime.sendMessage({ action: 'bioInputFocused', focused: focused }).catch(() => {}); + } + } catch (_) {} + } + + function mountBioInlineBar(textarea) { + if (!textarea) return null; + if (document.getElementById('fg-bio-inline-bar')) { + return document.getElementById('fg-bio-inline-bar'); + } + + const bar = document.createElement('div'); + bar.id = 'fg-bio-inline-bar'; + bar.style.cssText = ` + margin: 10px 0 6px 0 !important; + padding: 8px 10px !important; + background: #18181c !important; + border: 1px solid rgba(255, 255, 255, 0.15) !important; + border-radius: 12px !important; + display: flex !important; + flex-direction: column !important; + gap: 6px !important; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; + box-sizing: border-box !important; + user-select: none !important; + -webkit-user-select: none !important; + `; + + const topRow = document.createElement('div'); + topRow.style.cssText = ` + display: flex !important; + align-items: center !important; + justify-content: space-between !important; + font-size: 12px !important; + color: #d1d5db !important; + `; + + const titleSpan = document.createElement('span'); + titleSpan.innerHTML = `Bio Font`; + + const counterSpan = document.createElement('span'); + counterSpan.id = 'fg-bio-counter'; + counterSpan.style.cssText = ` + font-size: 11px !important; + font-weight: 600 !important; + color: #8e8e8e !important; + background: rgba(255, 255, 255, 0.06) !important; + padding: 2px 8px !important; + border-radius: 10px !important; + `; + counterSpan.textContent = '0 / 150'; + + topRow.appendChild(titleSpan); + topRow.appendChild(counterSpan); + + const chipsRow = document.createElement('div'); + chipsRow.style.cssText = ` + display: flex !important; + align-items: center !important; + gap: 6px !important; + overflow-x: auto !important; + scrollbar-width: none !important; + -webkit-overflow-scrolling: touch !important; + padding: 2px 0 !important; + `; + + const STYLES = [ + { id: 'normal', label: 'Normal' }, + { id: 'bold', label: 'Bold' }, + { id: 'sans', label: 'Sans' }, + { id: 'sans_italic', label: 'Italic' }, + { id: 'mono', label: 'Mono' }, + { id: 'gothic', label: 'Gothic' }, + { id: 'script', label: 'Script' } + ]; + + STYLES.forEach(st => { + const chip = document.createElement('button'); + chip.type = 'button'; + chip.className = 'fg-bio-chip'; + chip.dataset.styleId = st.id; + chip.textContent = st.label; + const isSelected = st.id === activeBioStyle; + chip.style.cssText = ` + padding: 5px 12px !important; + border-radius: 14px !important; + border: 1px solid ${isSelected ? '#ffffff' : 'rgba(255, 255, 255, 0.15)'} !important; + background: ${isSelected ? '#ffffff' : '#262626'} !important; + color: ${isSelected ? '#000000' : '#d1d5db'} !important; + font-size: 12px !important; + font-weight: ${isSelected ? '600' : '500'} !important; + white-space: nowrap !important; + cursor: pointer !important; + outline: none !important; + transition: background 0.15s ease, color 0.15s ease !important; + `; + + chip.addEventListener('click', (e) => { + e.preventDefault(); + applyBioStyleToTarget(st.id); + if (textarea) textarea.focus(); + }); + + chipsRow.appendChild(chip); + }); + + bar.appendChild(topRow); + bar.appendChild(chipsRow); + + if (textarea.parentElement) { + textarea.parentElement.insertBefore(bar, textarea); + } else { + textarea.before(bar); + } + + bioInlineBarEl = bar; + updateBioCharCounter(textarea); + return bar; + } + + function checkAndMountBioStylist() { + const bioEl = document.getElementById('pepBio') || + document.querySelector('textarea[aria-label="Bio"]') || + document.querySelector('textarea[placeholder="Bio"]') || + document.querySelector('textarea[name="biography"]'); + + if (bioEl) { + activeBioTarget = bioEl; + mountBioInlineBar(bioEl); + } + } + + // Intercept keystrokes for real-time live typing transformation + document.addEventListener('beforeinput', (e) => { + if (!isBioTarget(e.target) || activeBioStyle === 'normal') return; + if (e.data && e.inputType === 'insertText') { + e.preventDefault(); + const converted = convertStringToStyle(e.data, activeBioStyle); + document.execCommand('insertText', false, converted); + updateBioCharCounter(e.target); + } + }, true); + + document.addEventListener('input', (e) => { + if (!isBioTarget(e.target)) return; + updateBioCharCounter(e.target); + }, true); + + document.addEventListener('focusin', (e) => { + if (isBioTarget(e.target)) { + activeBioTarget = e.target; + mountBioInlineBar(e.target); + notifyBioFocus(true); + updateBioCharCounter(e.target); + } + }, true); + + document.addEventListener('focusout', (e) => { + if (isBioTarget(e.target)) { + setTimeout(() => { + const active = document.activeElement; + if (!isBioTarget(active)) { + notifyBioFocus(false); + } + }, 200); + } + }, true); + + // Watch for dynamic rendering of Bio textarea on /accounts/edit/ + const bioObserver = new MutationObserver(() => { + checkAndMountBioStylist(); + }); + bioObserver.observe(document.documentElement, { childList: true, subtree: true }); + setInterval(checkAndMountBioStylist, 500); + // Initialize immediately or upon DOM ready injectNativeStyles(); applyScrollSmoothing(); @@ -213,6 +535,7 @@ setupMediaUploadBridge(); enhanceFileInputsForVideoSupport(); preventLandscapeOrientationLock(); + checkAndMountBioStylist(); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { @@ -221,8 +544,9 @@ setupMediaUploadBridge(); enhanceFileInputsForVideoSupport(); preventLandscapeOrientationLock(); + checkAndMountBioStylist(); }); } - console.log('[FocusGram] Native Feel, Touch Smoothing, Media Upload Bridge & Video Support active.'); + console.log('[FocusGram] Native Feel, Bio Font Stylist & Video Support active.'); })(); diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/MainActivity.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/MainActivity.kt index d1d8dce..2d53f0f 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/MainActivity.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/MainActivity.kt @@ -27,6 +27,14 @@ class MainActivity : FragmentActivity() { } } + override fun onResume() { + super.onResume() + try { + val appIcon = com.ujwal.focusgram.core.datastore.SettingsRepository(this).getSettingsSync().appIcon + com.ujwal.focusgram.core.utils.AppIconManager.applyTaskDescription(this, appIcon) + } catch (_: Exception) {} + } + private fun applyHighRefreshRate() { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/datastore/SettingsRepository.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/datastore/SettingsRepository.kt index cda8ff9..38b3f9f 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/datastore/SettingsRepository.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/datastore/SettingsRepository.kt @@ -8,12 +8,14 @@ import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.longPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.preferences.core.stringSetPreferencesKey import androidx.datastore.preferences.preferencesDataStore import com.ujwal.focusgram.core.model.FocusSettings import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.runBlocking +import org.json.JSONObject private val Context.dataStore: DataStore by preferencesDataStore(name = "focusgram_settings") @@ -79,6 +81,15 @@ class SettingsRepository(private val context: Context) { notifySessionEnd = prefs[KEY_NOTIFY_SESSION_END] ?: false, notifyPersistent = prefs[KEY_NOTIFY_PERSISTENT] ?: false, portraitOnly = prefs[KEY_PORTRAIT_ONLY] ?: true, + appIcon = prefs[KEY_APP_ICON] ?: "default", + customIconsEnabled = prefs[KEY_CUSTOM_ICONS_ENABLED] ?: false, + + chatLockMode = prefs[KEY_CHAT_LOCK_MODE] ?: if (prefs[KEY_CHAT_LOCK_ALL] == true) "whole_dm" else "individual", + chatLockAll = (prefs[KEY_CHAT_LOCK_MODE] ?: if (prefs[KEY_CHAT_LOCK_ALL] == true) "whole_dm" else "individual") == "whole_dm", + lockedChatIds = prefs[KEY_LOCKED_CHAT_IDS] ?: emptySet(), + lockedChatUsernames = parseUsernamesMap(prefs[KEY_LOCKED_CHAT_USERNAMES]), + useSeparateChatPin = prefs[KEY_USE_SEPARATE_CHAT_PIN] ?: false, + chatBiometricEnabled = prefs[KEY_CHAT_BIOMETRIC_ENABLED] ?: true, ghostModeEnabled = prefs[KEY_GHOST_MODE_ENABLED] ?: false, ghostHideStorySeen = prefs[KEY_GHOST_HIDE_STORY_SEEN] ?: true, @@ -87,6 +98,22 @@ class SettingsRepository(private val context: Context) { ) } + private fun parseUsernamesMap(jsonStr: String?): Map { + if (jsonStr.isNullOrBlank()) return emptyMap() + return try { + val json = JSONObject(jsonStr) + val map = mutableMapOf() + val keys = json.keys() + while (keys.hasNext()) { + val k = keys.next() + map[k] = json.optString(k) + } + map + } catch (_: Exception) { + emptyMap() + } + } + val lastSessionEndTimestampFlow: Flow = context.dataStore.data.map { prefs -> prefs[KEY_LAST_SESSION_END_TIMESTAMP] ?: 0L } @@ -237,6 +264,105 @@ class SettingsRepository(private val context: Context) { context.dataStore.edit { it[key] = value } } + suspend fun setAppIcon(icon: String) = setString(KEY_APP_ICON, icon) + suspend fun setCustomIconsEnabled(enabled: Boolean) = setBoolean(KEY_CUSTOM_ICONS_ENABLED, enabled) + suspend fun setChatLockMode(mode: String) { + val cleanMode = when (mode.lowercase().trim()) { + "whole_dm", "whole", "all" -> "whole_dm" + "individual", "individual_dms", "single" -> "individual" + else -> "off" + } + context.dataStore.edit { prefs -> + prefs[KEY_CHAT_LOCK_MODE] = cleanMode + prefs[KEY_CHAT_LOCK_ALL] = (cleanMode == "whole_dm") + } + } + suspend fun setChatLockAll(enabled: Boolean) { + context.dataStore.edit { prefs -> + prefs[KEY_CHAT_LOCK_ALL] = enabled + prefs[KEY_CHAT_LOCK_MODE] = if (enabled) "whole_dm" else "individual" + } + } + suspend fun setLockedChatIds(ids: Set) { + context.dataStore.edit { prefs -> + prefs[KEY_LOCKED_CHAT_IDS] = ids + } + } + suspend fun addLockedChatId(id: String) { + val clean = id.trim().lowercase().removePrefix("@") + if (clean.isBlank()) return + context.dataStore.edit { prefs -> + val current = prefs[KEY_LOCKED_CHAT_IDS] ?: emptySet() + prefs[KEY_LOCKED_CHAT_IDS] = current + clean + } + } + suspend fun removeLockedChatId(id: String) { + val clean = id.trim().lowercase().removePrefix("@") + context.dataStore.edit { prefs -> + val current = prefs[KEY_LOCKED_CHAT_IDS] ?: emptySet() + val usernamesMap = parseUsernamesMap(prefs[KEY_LOCKED_CHAT_USERNAMES]).toMutableMap() + val mappedUser = usernamesMap[clean] + val toRemove = buildSet { + add(clean) + if (!mappedUser.isNullOrBlank()) add(mappedUser) + } + prefs[KEY_LOCKED_CHAT_IDS] = current - toRemove + usernamesMap.remove(clean) + if (!mappedUser.isNullOrBlank()) usernamesMap.remove(mappedUser) + prefs[KEY_LOCKED_CHAT_USERNAMES] = JSONObject(usernamesMap as Map<*, *>).toString() + } + } + suspend fun toggleLockedChat(threadId: String, username: String? = null): Boolean { + val cleanId = threadId.trim().lowercase() + if (cleanId.isBlank()) return false + val cleanUser = username?.trim()?.lowercase()?.removePrefix("@") + var isNowLocked = false + context.dataStore.edit { prefs -> + val currentIds = prefs[KEY_LOCKED_CHAT_IDS] ?: emptySet() + val usernamesMap = parseUsernamesMap(prefs[KEY_LOCKED_CHAT_USERNAMES]).toMutableMap() + val existingUser = usernamesMap[cleanId] ?: cleanUser + val matchesExisting = currentIds.contains(cleanId) || + (!cleanUser.isNullOrBlank() && currentIds.contains(cleanUser)) || + (!existingUser.isNullOrBlank() && currentIds.contains(existingUser)) + + if (matchesExisting) { + val toRemove = buildSet { + add(cleanId) + if (!cleanUser.isNullOrBlank()) add(cleanUser) + if (!existingUser.isNullOrBlank()) add(existingUser) + } + prefs[KEY_LOCKED_CHAT_IDS] = currentIds - toRemove + usernamesMap.remove(cleanId) + if (!cleanUser.isNullOrBlank()) usernamesMap.remove(cleanUser) + if (!existingUser.isNullOrBlank()) usernamesMap.remove(existingUser) + isNowLocked = false + } else { + prefs[KEY_LOCKED_CHAT_IDS] = currentIds + cleanId + val effectiveUser = if (!cleanUser.isNullOrBlank()) cleanUser else existingUser + if (!effectiveUser.isNullOrBlank()) { + usernamesMap[cleanId] = effectiveUser + usernamesMap[effectiveUser] = cleanId + } + isNowLocked = true + } + prefs[KEY_LOCKED_CHAT_USERNAMES] = JSONObject(usernamesMap as Map<*, *>).toString() + } + return isNowLocked + } + suspend fun mapThreadUsername(threadId: String, username: String) { + val cleanId = threadId.trim().lowercase() + val cleanUser = username.trim().lowercase().removePrefix("@") + if (cleanId.isBlank() || cleanUser.isBlank()) return + context.dataStore.edit { prefs -> + val usernamesMap = parseUsernamesMap(prefs[KEY_LOCKED_CHAT_USERNAMES]).toMutableMap() + usernamesMap[cleanId] = cleanUser + usernamesMap[cleanUser] = cleanId + prefs[KEY_LOCKED_CHAT_USERNAMES] = JSONObject(usernamesMap as Map<*, *>).toString() + } + } + suspend fun setUseSeparateChatPin(enabled: Boolean) = setBoolean(KEY_USE_SEPARATE_CHAT_PIN, enabled) + suspend fun setChatBiometricEnabled(enabled: Boolean) = setBoolean(KEY_CHAT_BIOMETRIC_ENABLED, enabled) + companion object { val KEY_NO_ADS = booleanPreferencesKey("no_ads") val KEY_NO_STORIES = booleanPreferencesKey("no_stories") @@ -295,5 +421,14 @@ class SettingsRepository(private val context: Context) { val KEY_GHOST_HIDE_DIRECT_SEEN = booleanPreferencesKey("ghost_hide_direct_seen") val KEY_GHOST_HIDE_TYPING = booleanPreferencesKey("ghost_hide_typing") val KEY_LAST_SESSION_END_TIMESTAMP = longPreferencesKey("last_session_end_timestamp") + + val KEY_APP_ICON = stringPreferencesKey("app_icon") + val KEY_CUSTOM_ICONS_ENABLED = booleanPreferencesKey("custom_icons_enabled") + val KEY_CHAT_LOCK_MODE = stringPreferencesKey("chat_lock_mode") + val KEY_CHAT_LOCK_ALL = booleanPreferencesKey("chat_lock_all") + val KEY_LOCKED_CHAT_IDS = stringSetPreferencesKey("locked_chat_ids") + val KEY_LOCKED_CHAT_USERNAMES = stringPreferencesKey("locked_chat_usernames") + val KEY_USE_SEPARATE_CHAT_PIN = booleanPreferencesKey("use_separate_chat_pin") + val KEY_CHAT_BIOMETRIC_ENABLED = booleanPreferencesKey("chat_biometric_enabled") } } diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/ExtensionManager.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/ExtensionManager.kt index cd834e4..d73ae30 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/ExtensionManager.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/ExtensionManager.kt @@ -6,6 +6,7 @@ import com.ujwal.focusgram.core.model.IslandMode import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import org.json.JSONArray import org.json.JSONObject import org.mozilla.geckoview.GeckoResult import org.mozilla.geckoview.GeckoRuntime @@ -28,6 +29,7 @@ class ExtensionManager(private val runtime: GeckoRuntime) { var onOpenSettings: (() -> Unit)? = null var onInputFocused: ((Boolean) -> Unit)? = null + var onBioInputFocused: ((Boolean) -> Unit)? = null var onUrlChanged: ((String) -> Unit)? = null var onModalOrChatActive: ((Boolean) -> Unit)? = null var onThemeChanged: ((String) -> Unit)? = null @@ -37,6 +39,9 @@ class ExtensionManager(private val runtime: GeckoRuntime) { var onDownloadError: ((error: String) -> Unit)? = null var onDownloadStarted: ((filename: String) -> Unit)? = null var onAuthStateChanged: ((isAuthenticated: Boolean, isAuthPage: Boolean) -> Unit)? = null + var onThreadUsernameMapped: ((threadId: String, usernames: List) -> Unit)? = null + var onToggleChatLock: ((threadId: String, username: String?) -> Unit)? = null + var onRequestUnlockChat: ((threadId: String, username: String?, targetUrl: String?) -> Unit)? = null /** * Installs and activates built-in content blocking and FocusGram controller from APK assets. @@ -136,6 +141,11 @@ class ExtensionManager(private val runtime: GeckoRuntime) { Log.d(TAG, "Received inputFocused from Instagram web: $focused") mainHandler.post { onInputFocused?.invoke(focused) } } + "bioInputFocused" -> { + val focused = json.optBoolean("focused", false) + Log.d(TAG, "Received bioInputFocused from Instagram web: $focused") + mainHandler.post { onBioInputFocused?.invoke(focused) } + } "urlChanged" -> { val url = json.optString("url") if (url.isNotEmpty()) { @@ -215,6 +225,52 @@ class ExtensionManager(private val runtime: GeckoRuntime) { onAuthStateChanged?.invoke(isAuthenticated, isAuthPage) } } + "threadUsernameMapped" -> { + val threadId = json.optString("threadId") + val usernamesArr = json.optJSONArray("usernames") + val singleUser = json.optString("username").takeIf { it.isNotBlank() } + val displayName = json.optString("displayName").takeIf { it.isNotBlank() } + val list = mutableListOf() + if (usernamesArr != null) { + for (i in 0 until usernamesArr.length()) { + val u = usernamesArr.optString(i) + if (u.isNotBlank()) list.add(u) + } + } + if (singleUser != null && !list.contains(singleUser)) { + list.add(0, singleUser) + } + if (displayName != null && !list.contains(displayName)) { + list.add(displayName) + } + if (threadId.isNotBlank()) { + Log.d(TAG, "Received threadUsernameMapped from web: threadId=$threadId, usernames=$list, displayName=$displayName") + mainHandler.post { + onThreadUsernameMapped?.invoke(threadId, list) + } + } + } + "requestUnlockChat" -> { + val threadId = json.optString("threadId") + val username = json.optString("username").takeIf { it.isNotBlank() } + val targetUrl = json.optString("targetUrl").takeIf { it.isNotBlank() } + if (threadId.isNotBlank()) { + Log.d(TAG, "Received requestUnlockChat from web: threadId=$threadId, username=$username, targetUrl=$targetUrl") + mainHandler.post { + onRequestUnlockChat?.invoke(threadId, username, targetUrl) + } + } + } + "toggleChatLock" -> { + val threadId = json.optString("threadId") + val username = json.optString("username").takeIf { it.isNotBlank() } + if (threadId.isNotBlank()) { + Log.d(TAG, "Received toggleChatLock from web: threadId=$threadId, username=$username") + mainHandler.post { + onToggleChatLock?.invoke(threadId, username) + } + } + } "getSettings" -> { activePort?.let { sendSettingsToPort(it, cachedSettings) } } @@ -254,6 +310,11 @@ class ExtensionManager(private val runtime: GeckoRuntime) { put("ghostHideStorySeen", settings.ghostHideStorySeen) put("ghostHideDirectSeen", settings.ghostHideDirectSeen) put("ghostHideTypingIndicator", settings.ghostHideTypingIndicator) + + put("chatLockMode", settings.chatLockMode) + put("chatLockAll", settings.chatLockAll) + put("lockedChatIds", JSONArray(settings.lockedChatIds.toList())) + put("lockedChatUsernames", JSONObject(settings.lockedChatUsernames)) } val msg = JSONObject().apply { @@ -262,12 +323,45 @@ class ExtensionManager(private val runtime: GeckoRuntime) { put("revealMode", settings.unblurMode) } port.postMessage(msg) - Log.d(TAG, "Broadcast settings to WebExtension: noAds=${settings.noAds}, ghost=${settings.ghostModeEnabled}, revealMode=${settings.unblurMode}") + Log.d(TAG, "Broadcast settings to WebExtension: noAds=${settings.noAds}, ghost=${settings.ghostModeEnabled}, chatLockAll=${settings.chatLockAll}, lockedChats=${settings.lockedChatIds.size}") } catch (e: Exception) { Log.e(TAG, "Failed to send settings to WebExtension port", e) } } + /** + * Informs WebExtension content script that a locked chat has successfully been unlocked. + */ + fun notifyChatUnlocked(threadId: String, isAll: Boolean = false) { + try { + val msg = JSONObject().apply { + put("action", "unlockChat") + put("threadId", threadId) + put("all", isAll) + } + activePort?.postMessage(msg) + Log.d(TAG, "Sent unlockChat to WebExtension port: threadId=$threadId, all=$isAll") + } catch (e: Exception) { + Log.e(TAG, "Failed sending unlockChat to WebExtension", e) + } + } + + /** + * Informs WebExtension content script that a conversation has been locked. + */ + fun notifyChatLocked(threadId: String) { + try { + val msg = JSONObject().apply { + put("action", "lockChat") + put("threadId", threadId) + } + activePort?.postMessage(msg) + Log.d(TAG, "Sent lockChat to WebExtension port: threadId=$threadId") + } catch (e: Exception) { + Log.e(TAG, "Failed sending lockChat to WebExtension", e) + } + } + /** * Senior Blueprint: Sets feed post reveal mode ("tap" or "hold") dynamically. */ @@ -380,6 +474,23 @@ class ExtensionManager(private val runtime: GeckoRuntime) { } } + /** + * Sends the active Unicode font style selection to the WebExtension content script + * for real-time live bio transformation. + */ + fun setBioStyle(style: String) { + try { + val msg = JSONObject().apply { + put("action", "setBioStyle") + put("style", style) + } + activePort?.postMessage(msg) + Log.d(TAG, "Sent setBioStyle ($style) to WebExtension port") + } catch (e: Exception) { + Log.e(TAG, "Failed to send setBioStyle to port: ${e.message}", e) + } + } + companion object { private const val TAG = "ExtensionManager" const val CONTENT_BLOCKER_EXTENSION_ID = "uBlock0@raymondhill.net" diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/FocusGramNavigationDelegate.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/FocusGramNavigationDelegate.kt index ba57fa7..958ec11 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/FocusGramNavigationDelegate.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/FocusGramNavigationDelegate.kt @@ -118,6 +118,25 @@ class FocusGramNavigationDelegate( } } Log.d(TAG, "Location changed to: $it") + val lower = it.lowercase() + if (lower.contains("/direct/t/")) { + val path = try { Uri.parse(it).path?.lowercase() ?: "" } catch (_: Exception) { "" } + val tid = path.removePrefix("/direct/t/").trim('/').split('/').firstOrNull()?.trim() ?: "" + val settings = sessionManager.currentSettings + val isLocked = if (settings.chatLockMode == "off") { + false + } else if (settings.chatLockMode == "whole_dm" || settings.chatLockAll) { + true + } else { + settings.lockedChatIds.any { lockedId -> + val clean = lockedId.trim().lowercase().removePrefix("@") + clean.equals(tid, ignoreCase = true) || lower.contains(clean) + } + } + if (isLocked) { + session.loadUri("javascript:(function(){if(typeof window.__fgApplyPrivacyVeil==='function'){window.__fgApplyPrivacyVeil();}})()") + } + } sessionManager.updateCurrentUrl(it) onRouteChanged?.invoke(it) sessionManager.injectBottomBarTrimmer() diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/GeckoSessionManager.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/GeckoSessionManager.kt index d010c77..d2fef14 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/GeckoSessionManager.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/GeckoSessionManager.kt @@ -52,7 +52,7 @@ class GeckoSessionManager(private val runtime: GeckoRuntime) { isAuthenticated = auth if (auth && changed) { val url = _currentUrl.value.lowercase() - val isAuth = url.contains("/accounts") || url.contains("/login") || url.contains("/signup") + val isAuth = (url.contains("/accounts") && !url.contains("/accounts/edit")) || url.contains("/login") || url.contains("/signup") if (!isAuth) { injectBottomBarTrimmer() userScriptManager?.injectAll(session, currentSettings) @@ -91,7 +91,7 @@ class GeckoSessionManager(private val runtime: GeckoRuntime) { _progress.value = 100 if (success) { val url = _currentUrl.value.lowercase() - val isAuth = url.contains("/accounts") || url.contains("/login") || url.contains("/signup") + val isAuth = (url.contains("/accounts") && !url.contains("/accounts/edit")) || url.contains("/login") || url.contains("/signup") if (isAuthenticated && !isAuth) { injectBottomBarTrimmer() userScriptManager?.injectAll(session, currentSettings) @@ -212,11 +212,15 @@ class GeckoSessionManager(private val runtime: GeckoRuntime) { target = document.querySelector('svg[aria-label="Reels"]')?.closest('a') || document.querySelector('a[href*="/reels"]') || document.querySelector('a[href*="/reel/"]'); - } else if (p.indexOf('direct') !== -1) { + } else if (p == "/direct" || p == "/direct/" || p == "/direct/inbox" || p == "/direct/inbox/") { target = document.querySelector('svg[aria-label="Messages"]')?.closest('a') || document.querySelector('svg[aria-label="Direct"]')?.closest('a') || - document.querySelector('a[href*="/direct/inbox"]') || - document.querySelector('a[href*="/direct"]'); + document.querySelector('a[href="/direct/inbox/"]') || + document.querySelector('a[href="/direct/inbox"]') || + document.querySelector('a[href="/direct/"]'); + } else if (p.indexOf('/direct/t/') !== -1) { + target = document.querySelector('a[href*="' + p + '"]') || + document.querySelector('a[href*="' + p.replace(/\/$/, '') + '"]'); } if (!target) { target = document.querySelector('a[href="' + p + '"]') || @@ -300,7 +304,7 @@ class GeckoSessionManager(private val runtime: GeckoRuntime) { val js = """javascript:(function() { try { var p = (window.location.pathname || '').toLowerCase(); - if (p.startsWith('/direct') || p.startsWith('/accounts') || p.startsWith('/login') || p.startsWith('/signup')) return; + if (p.startsWith('/direct') || (p.startsWith('/accounts') && !p.startsWith('/accounts/edit')) || p.startsWith('/login') || p.startsWith('/signup')) return; var c = document.cookie || ''; if ((p === '/' || p === '') && !c.includes('sessionid=') && !c.includes('ds_user_id=')) return; if (document.getElementById('loginForm') || document.querySelector('form[action*="login"], input[name="password"]')) return; diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/UserScriptManager.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/UserScriptManager.kt index 663ac36..0847e46 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/UserScriptManager.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/engine/UserScriptManager.kt @@ -30,6 +30,8 @@ class UserScriptManager(private val context: Context) { * and broadcasts updates to active scripts. */ fun injectConfig(session: GeckoSession, settings: FocusSettings) { + val lockedIdsJson = org.json.JSONArray(settings.lockedChatIds.map { it.lowercase().trim().removePrefix("@") }).toString() + val lockedUsersJson = org.json.JSONObject(settings.lockedChatUsernames).toString() val configJs = """ (function() { window.__FOCUSGRAM_CONFIG__ = { @@ -59,6 +61,24 @@ class UserScriptManager(private val context: Context) { igSeen: ${settings.ghostHideDirectSeen}, igTyping: ${settings.ghostHideTypingIndicator} }; + window.__fgChatLockMode = '${settings.chatLockMode}'; + window.__fgChatLockAll = ${settings.chatLockAll || settings.chatLockMode == "whole_dm"}; + window.__fgLockedChatIds = $lockedIdsJson; + window.__fgLockedChatUsernames = $lockedUsersJson; + window.__fgThreadUsernameMap = $lockedUsersJson; + + const syncDetail = { + chatLockMode: '${settings.chatLockMode}', + chatLockAll: ${settings.chatLockAll || settings.chatLockMode == "whole_dm"}, + lockedChatIds: $lockedIdsJson, + lockedChatUsernames: $lockedUsersJson, + threadUsernameMap: $lockedUsersJson + }; + try { + window.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { detail: syncDetail })); + document.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { detail: syncDetail })); + } catch(_) {} + if (window.__focusgramUpdateStyles) { window.__focusgramUpdateStyles(); } diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/FocusSettings.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/FocusSettings.kt index 85d7f01..10df1cc 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/FocusSettings.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/FocusSettings.kt @@ -63,6 +63,16 @@ data class FocusSettings( val notifySessionEnd: Boolean = false, val notifyPersistent: Boolean = false, val portraitOnly: Boolean = true, + val appIcon: String = "default", + val customIconsEnabled: Boolean = false, + + // Chat Lock & Direct Message Privacy + val chatLockMode: String = "individual", // "off", "individual", "whole_dm" + val chatLockAll: Boolean = false, + val lockedChatIds: Set = emptySet(), + val lockedChatUsernames: Map = emptyMap(), + val useSeparateChatPin: Boolean = false, + val chatBiometricEnabled: Boolean = true, // Ghost Mode (Privacy & Stealth) val ghostModeEnabled: Boolean = false, diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/IslandMode.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/IslandMode.kt index 3a001c8..af03788 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/IslandMode.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/model/IslandMode.kt @@ -44,7 +44,7 @@ enum class IslandMode { val path = extractPath(url) return when { - path.startsWith("/accounts/") || path.startsWith("/login") || path.startsWith("/signup") -> HIDDEN + (path.startsWith("/accounts/") && !path.startsWith("/accounts/edit")) || path.startsWith("/login") || path.startsWith("/signup") -> HIDDEN path.startsWith("/direct") -> HIDDEN path.contains("/comments") -> HIDDEN path.startsWith("/stories/") -> HIDDEN diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/security/EncryptedStorage.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/security/EncryptedStorage.kt index a6d4d13..2efafd8 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/security/EncryptedStorage.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/security/EncryptedStorage.kt @@ -82,6 +82,46 @@ class EncryptedStorage(context: Context) { Log.i(TAG, "App Lock PIN removed from vault.") } + // --- Chat Lock PIN Management --- + + fun saveChatPin(pin: String) { + val hashedPin = hashPin("chat_$pin") + securePrefs.edit() + .putString(KEY_CHAT_PIN_HASH, hashedPin) + .putBoolean(KEY_HAS_CHAT_PIN, true) + .apply() + resetFailedAttempts() + Log.i(TAG, "Chat Lock PIN securely stored in MasterKey AES-GCM vault.") + } + + fun verifyChatPin(enteredPin: String): Boolean { + if (isLockedOut()) { + Log.w(TAG, "Chat PIN verification rejected: Vault is currently locked out.") + return false + } + val storedHash = securePrefs.getString(KEY_CHAT_PIN_HASH, null) ?: return false + val enteredHash = hashPin("chat_$enteredPin") + val isValid = storedHash == enteredHash + if (isValid) { + resetFailedAttempts() + } else { + recordFailedAttempt() + } + return isValid + } + + fun hasChatPin(): Boolean { + return securePrefs.getBoolean(KEY_HAS_CHAT_PIN, false) && securePrefs.getString(KEY_CHAT_PIN_HASH, null) != null + } + + fun clearChatPin() { + securePrefs.edit() + .remove(KEY_CHAT_PIN_HASH) + .putBoolean(KEY_HAS_CHAT_PIN, false) + .apply() + Log.i(TAG, "Chat Lock PIN removed from vault.") + } + // --- Brute Force Protection --- fun isLockedOut(): Boolean { @@ -138,6 +178,8 @@ class EncryptedStorage(context: Context) { private const val KEY_PIN_HASH = "vault_pin_hash" private const val KEY_HAS_PIN = "vault_has_pin" + private const val KEY_CHAT_PIN_HASH = "vault_chat_pin_hash" + private const val KEY_HAS_CHAT_PIN = "vault_has_chat_pin" private const val KEY_FAILED_ATTEMPTS = "vault_failed_attempts" private const val KEY_LOCKOUT_UNTIL = "vault_lockout_until" diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/AppIconManager.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/AppIconManager.kt new file mode 100644 index 0000000..38d738b --- /dev/null +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/AppIconManager.kt @@ -0,0 +1,285 @@ +package com.ujwal.focusgram.core.utils + +import android.app.Activity +import android.app.ActivityManager +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.os.Build +import android.util.Log +import androidx.annotation.DrawableRes +import androidx.core.content.pm.ShortcutInfoCompat +import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.graphics.drawable.IconCompat +import com.ujwal.focusgram.MainActivity +import com.ujwal.focusgram.R + +/** + * AppIconManager + * Controls dynamic launcher icon switching via Android PackageManager activity-alias toggles. + * LITERALLY replaces the app icon across Home Screen, App Drawer, Recents Page, and App Info page. + * Safe, purely client-side, with DONT_KILL_APP flag to avoid killing running tasks. + */ +object AppIconManager { + private const val TAG = "AppIconManager" + + enum class IconOption( + val id: String, + val aliasSuffix: String, + val displayName: String, + val subtitle: String, + val category: String, + @DrawableRes val iconRes: Int + ) { + // --- Core Icons --- + DEFAULT( + id = "default", + aliasSuffix = "MainActivityDefault", + displayName = "FocusGram Classic", + subtitle = "Signature focus gradient on dark", + category = "Core", + iconRes = R.mipmap.ic_launcher + ), + PITCH_BLACK( + id = "pitch_black", + aliasSuffix = "MainActivityPitchBlack", + displayName = "Pitch Black", + subtitle = "True OLED stealth black aesthetic", + category = "Core", + iconRes = R.mipmap.ic_launcher_pitch_black + ), + ALL_WHITE( + id = "all_white", + aliasSuffix = "MainActivityAllWhite", + displayName = "All White", + subtitle = "Minimalist bright white with clean camera", + category = "Core", + iconRes = R.mipmap.ic_launcher_all_white + ), + + // --- Custom Redesigns (alt-logos) --- + REDESIGN( + id = "redesign", + aliasSuffix = "MainActivityRedesign", + displayName = "FocusGram Redesign", + subtitle = "Official modern brand redesign", + category = "Redesigns", + iconRes = R.mipmap.ic_launcher_redesign + ), + ABSTRACT( + id = "abstract", + aliasSuffix = "MainActivityAbstract", + displayName = "Abstract Art", + subtitle = "Geometric gradient art redesign", + category = "Redesigns", + iconRes = R.mipmap.ic_launcher_abstract + ), + FOREST( + id = "forest", + aliasSuffix = "MainActivityForest", + displayName = "Forest Nature", + subtitle = "Earthy organic botanical tones", + category = "Redesigns", + iconRes = R.mipmap.ic_launcher_forest + ), + GOLDEN( + id = "golden", + aliasSuffix = "MainActivityGolden", + displayName = "Golden Luxury", + subtitle = "Deep gold emblem on obsidian", + category = "Redesigns", + iconRes = R.mipmap.ic_launcher_golden + ), + METAL( + id = "metal", + aliasSuffix = "MainActivityMetal", + displayName = "Titanium Metal", + subtitle = "Brushed industrial steel & chrome", + category = "Redesigns", + iconRes = R.mipmap.ic_launcher_metal + ), + SCRIBBLE( + id = "scribble", + aliasSuffix = "MainActivityScribble", + displayName = "Scribble Sketch", + subtitle = "Handcrafted playful illustration", + category = "Redesigns", + iconRes = R.mipmap.ic_launcher_scribble + ), + + // --- Originals (Authentic Brand History) --- + POLAROID( + id = "polaroid", + aliasSuffix = "MainActivityPolaroid", + displayName = "Polaroid Camera", + subtitle = "Iconic 2010 debut with rainbow stripe", + category = "Originals", + iconRes = R.mipmap.ic_launcher_polaroid + ), + VIEWFINDER( + id = "viewfinder", + aliasSuffix = "MainActivityViewfinder", + displayName = "Viewfinder", + subtitle = "2011 classic retro leather camera", + category = "Originals", + iconRes = R.mipmap.ic_launcher_viewfinder + ), + MINIMALIST( + id = "minimalist", + aliasSuffix = "MainActivityMinimalist", + displayName = "Minimalist Colors", + subtitle = "2016 breakthrough flat sunset gradient", + category = "Originals", + iconRes = R.mipmap.ic_launcher_minimalist + ), + VIBRANT( + id = "vibrant", + aliasSuffix = "MainActivityVibrant", + displayName = "Vibrant Gradient", + subtitle = "2022 radiant illuminated brand design", + category = "Originals", + iconRes = R.mipmap.ic_launcher_vibrant + ); + + companion object { + fun fromId(id: String): IconOption { + return values().firstOrNull { it.id.equals(id, ignoreCase = true) } ?: DEFAULT + } + } + } + + /** + * Atomically switches active launcher icon by enabling the chosen alias and disabling others. + * Replaces the app icon on Home Screen, App Drawer (App Screen), and App Info (System Settings). + * Also updates the running Activity's Recents overview TaskDescription immediately. + */ + fun setAppIcon(context: Context, iconId: String) { + val targetOption = IconOption.fromId(iconId) + val packageManager = context.packageManager + val packageName = context.packageName + + Log.i(TAG, "Switching app icon to: ${targetOption.displayName} (${targetOption.aliasSuffix})") + + // 1. Enable target alias so there's always at least one enabled launcher entry point + try { + val targetComponent = ComponentName(packageName, "$packageName.${targetOption.aliasSuffix}") + packageManager.setComponentEnabledSetting( + targetComponent, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP + ) + } catch (e: Exception) { + Log.e(TAG, "Failed enabling target launcher alias ${targetOption.aliasSuffix}: ${e.message}", e) + } + + // 2. Disable all other aliases + for (option in IconOption.values()) { + if (option == targetOption) continue + try { + val comp = ComponentName(packageName, "$packageName.${option.aliasSuffix}") + packageManager.setComponentEnabledSetting( + comp, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP + ) + } catch (e: Exception) { + Log.w(TAG, "Failed disabling launcher alias ${option.aliasSuffix}: ${e.message}") + } + } + + // 3. Immediately update TaskDescription for the Recents screen + if (context is Activity) { + applyTaskDescription(context, iconId) + } + } + + /** + * Updates the Activity's TaskDescription so the Recents / Multitasking overview screen + * reflects the exact chosen icon and label immediately. + */ + fun applyTaskDescription(activity: Activity, iconId: String) { + try { + val option = IconOption.fromId(iconId) + val label = activity.getString(R.string.app_name) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + val taskDesc = ActivityManager.TaskDescription.Builder() + .setLabel(label) + .setIcon(option.iconRes) + .build() + activity.setTaskDescription(taskDesc) + } else { + val bmp = BitmapFactory.decodeResource(activity.resources, option.iconRes) + @Suppress("DEPRECATION") + val taskDesc = ActivityManager.TaskDescription(label, bmp) + activity.setTaskDescription(taskDesc) + } + } catch (e: Exception) { + Log.w(TAG, "Failed applying TaskDescription for Recents screen: ${e.message}") + } + } + + /** + * Pins a custom home screen shortcut with a user-provided or dynamically downloaded bitmap. + * Uses ShortcutManagerCompat to support pinning on supported Android launchers. + */ + fun pinCustomShortcut(context: Context, bitmap: Bitmap, label: String = "Instagram"): Boolean { + if (!ShortcutManagerCompat.isRequestPinShortcutSupported(context)) { + Log.w(TAG, "Pin shortcut is not supported by current launcher") + return false + } + + return try { + val launchIntent = Intent(context, MainActivity::class.java).apply { + action = Intent.ACTION_MAIN + addCategory(Intent.CATEGORY_LAUNCHER) + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + } + + val iconCompat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + IconCompat.createWithAdaptiveBitmap(bitmap) + } else { + IconCompat.createWithBitmap(bitmap) + } + + val shortcutId = "focusgram_icon_${System.currentTimeMillis()}" + val shortcut = ShortcutInfoCompat.Builder(context, shortcutId) + .setShortLabel(label) + .setIcon(iconCompat) + .setIntent(launchIntent) + .build() + + ShortcutManagerCompat.requestPinShortcut(context, shortcut, null) + } catch (e: Exception) { + Log.e(TAG, "Failed to pin custom shortcut: ${e.message}", e) + false + } + } + + private val iconCache = mutableMapOf() + + /** + * Safely rasterizes any Android drawable (AdaptiveIconDrawable, VectorDrawable, BitmapDrawable) + * onto an in-memory ARGB_8888 Bitmap for Compose rendering without crashing on adaptive icons. + */ + fun getIconBitmap(context: Context, @DrawableRes resId: Int): Bitmap? { + iconCache[resId]?.let { return it } + return try { + val drawable = androidx.core.content.ContextCompat.getDrawable(context, resId) ?: return null + val width = if (drawable.intrinsicWidth > 0) drawable.intrinsicWidth else 192 + val height = if (drawable.intrinsicHeight > 0) drawable.intrinsicHeight else 192 + val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + val canvas = android.graphics.Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + iconCache[resId] = bitmap + bitmap + } catch (e: Exception) { + Log.e(TAG, "Failed creating icon bitmap for resId $resId: ${e.message}", e) + null + } + } +} diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/HistoricalIconManager.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/HistoricalIconManager.kt new file mode 100644 index 0000000..185cc4f --- /dev/null +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/core/utils/HistoricalIconManager.kt @@ -0,0 +1,156 @@ +package com.ujwal.focusgram.core.utils + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.util.Log +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.withContext +import java.io.File +import java.io.FileOutputStream +import java.net.HttpURLConnection +import java.net.URL + +/** + * OriginalIcon (Historical Instagram Brand Icon) + * Represents an authentic Instagram brand era logo downloaded dynamically on demand. + */ +data class OriginalIcon( + val id: String, + val title: String, + val subtitle: String, + val downloadUrl: String, + val year: String = "" +) + +typealias HistoricalIcon = OriginalIcon + +/** + * HistoricalIconManager + * Dynamically downloads authentic original Instagram brand logos on demand, + * preventing any APK size bloat. + */ +object HistoricalIconManager { + private const val TAG = "HistoricalIconManager" + + val ORIGINAL_ICONS = listOf( + OriginalIcon( + id = "polaroid_camera", + title = "Polaroid Camera", + subtitle = "Iconic debut Polaroid camera with rainbow stripe", + downloadUrl = "https://logovent.com/blog/wp-content/uploads/2024/06/Polaroid-Camera-Instagram-Logo.png" + ), + OriginalIcon( + id = "viewfinder", + title = "Viewfinder", + subtitle = "Retro brown leather camera with viewfinder banner", + downloadUrl = "https://logovent.com/blog/wp-content/uploads/2024/06/Viewfinder-Logo.png" + ), + OriginalIcon( + id = "minimalist_colors", + title = "Minimalist Colors", + subtitle = "Flat minimalist neon sunset camera outline", + downloadUrl = "https://logovent.com/blog/wp-content/uploads/2024/06/Minimalist-with-Colors.png" + ), + OriginalIcon( + id = "vibrant_version", + title = "Vibrant Gradient", + subtitle = "Refined brand identity with vibrant illumination", + downloadUrl = "https://logovent.com/blog/wp-content/uploads/2024/06/Vibrant-Version.png" + ) + ) + + val HISTORICAL_ICONS = ORIGINAL_ICONS + + private val _downloadedIcons = MutableStateFlow>(emptyMap()) + val downloadedIcons: StateFlow> = _downloadedIcons.asStateFlow() + + private val _isLoading = MutableStateFlow(false) + val isLoading: StateFlow = _isLoading.asStateFlow() + + private val _downloadProgress = MutableStateFlow(0f) + val downloadProgress: StateFlow = _downloadProgress.asStateFlow() + + /** + * Ensures all original icons are loaded from cache or downloaded on-the-fly. + */ + suspend fun loadHistoricalIcons(context: Context) { + if (_isLoading.value) return + withContext(Dispatchers.IO) { + _isLoading.value = true + try { + val iconDir = File(context.cacheDir, "original_icons").apply { mkdirs() } + val loadedMap = HashMap() + + // 1. First check existing disk cache + for (icon in ORIGINAL_ICONS) { + val file = File(iconDir, "${icon.id}.png") + if (file.exists() && file.length() > 0) { + decodeBitmapSafely(file)?.let { loadedMap[icon.id] = it } + } + } + _downloadedIcons.value = loadedMap.toMap() + + // 2. Identify missing icons to download + val missing = ORIGINAL_ICONS.filter { !loadedMap.containsKey(it.id) } + if (missing.isEmpty()) { + _downloadProgress.value = 1f + return@withContext + } + + var completed = 0 + for (icon in missing) { + val file = File(iconDir, "${icon.id}.png") + try { + val connection = (URL(icon.downloadUrl).openConnection() as HttpURLConnection).apply { + connectTimeout = 10000 + readTimeout = 15000 + setRequestProperty("User-Agent", "FocusGram/1.0 (Android; Mobile)") + } + if (connection.responseCode in 200..299) { + connection.inputStream.use { input -> + FileOutputStream(file).use { output -> + input.copyTo(output) + } + } + decodeBitmapSafely(file)?.let { bitmap -> + loadedMap[icon.id] = bitmap + _downloadedIcons.value = loadedMap.toMap() + } + } + } catch (e: Exception) { + Log.e(TAG, "Failed downloading icon ${icon.id}: ${e.message}", e) + } + completed++ + _downloadProgress.value = completed.toFloat() / missing.size + } + } finally { + _isLoading.value = false + } + } + } + + private fun decodeBitmapSafely(file: File): Bitmap? { + return try { + val options = BitmapFactory.Options().apply { + inJustDecodeBounds = true + } + BitmapFactory.decodeFile(file.absolutePath, options) + + var inSampleSize = 1 + while (options.outWidth / inSampleSize > 512 || options.outHeight / inSampleSize > 512) { + inSampleSize *= 2 + } + val decodeOptions = BitmapFactory.Options().apply { + this.inSampleSize = inSampleSize + } + BitmapFactory.decodeFile(file.absolutePath, decodeOptions) + } catch (e: Exception) { + Log.e(TAG, "Error decoding file ${file.name}: ${e.message}") + null + } + } +} diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockScreen.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockScreen.kt index 015ca93..bfcb267 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockScreen.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Backspace import androidx.compose.material.icons.filled.Fingerprint @@ -67,6 +68,8 @@ fun AppLockScreen( isBiometricAllowed: Boolean = true, title: String = "FocusGram is Locked", subtitle: String = "Enter your PIN to unlock", + customVerifyPin: ((String) -> Boolean)? = null, + onCancel: (() -> Unit)? = null, onUnlockSuccess: () -> Unit ) { val context = LocalContext.current @@ -120,7 +123,7 @@ fun AppLockScreen( ) val promptInfo = BiometricPrompt.PromptInfo.Builder() - .setTitle("Unlock FocusGram") + .setTitle(title) .setSubtitle("Confirm your biometric to proceed") .setNegativeButtonText("Use PIN") .build() @@ -129,9 +132,11 @@ fun AppLockScreen( } } - // Trigger BiometricPrompt if enabled and available - LaunchedEffect(Unit) { - triggerBiometricPrompt() + // Trigger BiometricPrompt only if enabled and allowed + LaunchedEffect(isBiometricAllowed) { + if (isBiometricAllowed) { + triggerBiometricPrompt() + } } fun verifyEnteredPin(pin: String) { @@ -142,7 +147,11 @@ fun AppLockScreen( return } - val isValid = encryptedStorage.verifyPin(pin) + val isValid = if (customVerifyPin != null) { + customVerifyPin(pin) + } else { + encryptedStorage.verifyPin(pin) + } if (isValid) { onUnlockSuccess() } else { @@ -200,6 +209,26 @@ fun AppLockScreen( .padding(horizontal = 32.dp), horizontalAlignment = Alignment.CenterHorizontally ) { + if (onCancel != null) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + horizontalArrangement = Arrangement.Start + ) { + Text( + text = "Cancel", + color = InstagramBlue, + fontSize = 16.sp, + fontWeight = FontWeight.Medium, + modifier = Modifier + .clip(RoundedCornerShape(8.dp)) + .clickable { onCancel() } + .padding(vertical = 6.dp, horizontal = 4.dp) + ) + } + } + Spacer(modifier = Modifier.weight(1f)) // Lock Icon @@ -277,11 +306,12 @@ fun AppLockScreen( .padding(bottom = 24.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { + val bioKey = if (isBiometricAllowed) "BIO" else "" val keypadRows = listOf( listOf("1", "2", "3"), listOf("4", "5", "6"), listOf("7", "8", "9"), - listOf("BIO", "0", "DEL") + listOf(bioKey, "0", "DEL") ) for (row in keypadRows) { @@ -340,6 +370,7 @@ private fun KeypadButton( tint = InstagramBlue, modifier = Modifier.size(28.dp) ) + "" -> {} else -> Text( text = key, fontSize = 26.sp, diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSettingsPage.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSettingsPage.kt index 059f32d..8c42074 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSettingsPage.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSettingsPage.kt @@ -1,52 +1,48 @@ package com.ujwal.focusgram.feature.applock +import androidx.activity.compose.BackHandler import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBars import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Fingerprint import androidx.compose.material.icons.filled.Lock -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Text +import androidx.compose.material.icons.filled.Schedule import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.ujwal.focusgram.core.datastore.SettingsRepository import com.ujwal.focusgram.core.model.FocusSettings import com.ujwal.focusgram.core.security.EncryptedStorage -import androidx.activity.compose.BackHandler -import com.ujwal.focusgram.core.ui.components.FocusGramCard -import com.ujwal.focusgram.core.ui.components.FocusGramSectionHeader -import com.ujwal.focusgram.core.ui.components.FocusGramToggleRow import com.ujwal.focusgram.core.ui.components.FocusGramTopBar -import com.ujwal.focusgram.core.ui.theme.AlertRed -import com.ujwal.focusgram.core.ui.theme.InstagramBlue +import com.ujwal.focusgram.core.ui.components.IOSGroupedCard +import com.ujwal.focusgram.core.ui.components.IOSSectionTitle +import com.ujwal.focusgram.core.ui.components.IOSSettingsRow import com.ujwal.focusgram.core.ui.theme.PureBlack import kotlinx.coroutines.launch -/** - * AppLockSettingsPage - * Configure PIN protection, biometric sensor authentication, and auto-lock timeout. - */ +private val IOSBlue = Color(0xFF007AFF) +private val IOSGreen = Color(0xFF34C759) +private val IOSOrange = Color(0xFFFF9500) + @Composable fun AppLockSettingsPage( repository: SettingsRepository, encryptedStorage: EncryptedStorage, onBack: () -> Unit, onChangePin: () -> Unit, + onChangeChatPin: () -> Unit = {}, modifier: Modifier = Modifier ) { val settings by repository.settingsFlow.collectAsState(initial = FocusSettings()) @@ -63,88 +59,86 @@ fun AppLockSettingsPage( .padding(WindowInsets.statusBars.asPaddingValues()) ) { FocusGramTopBar( - title = "App Lock Settings", + title = "App Lock", onBack = onBack ) LazyColumn( modifier = Modifier .fillMaxSize() - .padding(horizontal = 16.dp), - verticalArrangement = Arrangement.spacedBy(12.dp) + .padding(horizontal = 16.dp) ) { item { - FocusGramSectionHeader( - title = "Security Guard", - subtitle = "Restrict app access to prevent unconscious Instagram opens" - ) - } - - item { - FocusGramToggleRow( - title = "Enable App Lock", - subtitle = if (settings.appLockEnabled) "App requires 4-digit PIN to open" else "Disabled", - checked = settings.appLockEnabled, - onCheckedChange = { isChecked -> - if (isChecked && !encryptedStorage.hasPin()) { - onChangePin() - } else { - scope.launch { repository.setAppLock(isChecked, settings.biometricEnabled) } - } - }, - icon = Icons.Default.Lock - ) + IOSSectionTitle(title = "APP PROTECTION") + IOSGroupedCard { + IOSSettingsRow( + title = "App Lock Protection", + subtitle = "Require 4-digit PIN or biometrics upon opening FocusGram", + icon = Icons.Default.Lock, + iconBgColor = IOSBlue, + checked = settings.appLockEnabled, + onCheckedChange = { isChecked -> + scope.launch { + repository.setAppLock(isChecked, settings.biometricEnabled) + } + if (isChecked && !encryptedStorage.hasPin()) { + onChangePin() + } + }, + showDivider = false + ) + } } if (settings.appLockEnabled) { item { - FocusGramToggleRow( - title = "Biometric Unlock", - subtitle = "Use fingerprint or face recognition to unlock", - checked = settings.biometricEnabled, - onCheckedChange = { scope.launch { repository.setAppLock(true, it) } } - ) - } - - item { - FocusGramToggleRow( - title = "Auto-Lock on Background", - subtitle = "Immediately lock whenever leaving FocusGram", - checked = settings.autoLockOnBackground, - onCheckedChange = { isChecked -> - scope.launch { repository.setAutoLockBackground(isChecked) } - } - ) - } - - item { - Spacer(modifier = Modifier.height(10.dp)) - Button( - onClick = onChangePin, - modifier = Modifier.fillMaxWidth(), - colors = ButtonDefaults.buttonColors(containerColor = InstagramBlue) - ) { - Text("Change PIN", color = PureBlack) + IOSSectionTitle(title = "AUTHENTICATION METHOD") + IOSGroupedCard { + IOSSettingsRow( + title = "Biometric Unlock", + subtitle = "Use fingerprint or face unlock", + icon = Icons.Default.Fingerprint, + iconBgColor = IOSGreen, + checked = settings.biometricEnabled, + onCheckedChange = { isChecked -> + scope.launch { + repository.setAppLock(settings.appLockEnabled, isChecked) + } + } + ) + IOSSettingsRow( + title = if (encryptedStorage.hasPin()) "Change 4-Digit PIN" else "Set 4-Digit PIN", + subtitle = "Update master passcode for app entry", + icon = Icons.Default.Lock, + iconBgColor = IOSOrange, + onClick = onChangePin, + showDivider = false + ) } } item { - OutlinedButton( - onClick = { - scope.launch { - encryptedStorage.clearPin() - repository.setAppLock(enabled = false, biometric = false) - } - }, - modifier = Modifier.fillMaxWidth() - ) { - Text("Disable & Remove PIN", color = AlertRed) + IOSSectionTitle(title = "AUTO-LOCK BEHAVIOR") + IOSGroupedCard { + IOSSettingsRow( + title = "Auto-Lock in Background", + subtitle = "Lock immediately whenever FocusGram is minimized", + icon = Icons.Default.Schedule, + iconBgColor = Color(0xFF636366), + checked = settings.autoLockOnBackground, + onCheckedChange = { isChecked -> + scope.launch { + repository.setAutoLockBackground(isChecked) + } + }, + showDivider = false + ) } } } item { - Spacer(modifier = Modifier.height(30.dp)) + Spacer(modifier = Modifier.height(40.dp)) } } } diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSetupScreen.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSetupScreen.kt index 4d17531..27b6434 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSetupScreen.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/AppLockSetupScreen.kt @@ -61,6 +61,9 @@ fun AppLockSetupScreen( settingsRepository: SettingsRepository, onBack: () -> Unit, onSuccess: () -> Unit, + title: String = "Set App Lock PIN", + subtitle: String = "Used to unlock FocusGram and secure your mindful limits.", + isChatPinSetup: Boolean = false, modifier: Modifier = Modifier ) { var step by remember { mutableStateOf(1) } // 1: Enter, 2: Confirm @@ -89,8 +92,13 @@ fun AppLockSetupScreen( if (firstPin == confirmPin) { view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP) scope.launch { - encryptedStorage.savePin(confirmPin) - settingsRepository.setAppLock(enabled = true, biometric = false) + if (isChatPinSetup) { + encryptedStorage.saveChatPin(confirmPin) + settingsRepository.setUseSeparateChatPin(true) + } else { + encryptedStorage.savePin(confirmPin) + settingsRepository.setAppLock(enabled = true, biometric = false) + } onSuccess() } } else { @@ -121,7 +129,7 @@ fun AppLockSetupScreen( .padding(WindowInsets.statusBars.asPaddingValues()) ) { FocusGramTopBar( - title = "Set App Lock PIN", + title = title, onBack = onBack ) @@ -160,7 +168,7 @@ fun AppLockSetupScreen( Spacer(modifier = Modifier.height(6.dp)) Text( - text = "Used to unlock FocusGram and secure your mindful limits.", + text = subtitle, style = MaterialTheme.typography.bodySmall, color = TextSecondary ) diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/ChatLockScreen.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/ChatLockScreen.kt new file mode 100644 index 0000000..60980c4 --- /dev/null +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/applock/ChatLockScreen.kt @@ -0,0 +1,463 @@ +package com.ujwal.focusgram.feature.applock + +import androidx.biometric.BiometricManager +import androidx.biometric.BiometricPrompt +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.keyframes +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.Backspace +import androidx.compose.material.icons.filled.Fingerprint +import androidx.compose.material.icons.filled.Lock +import androidx.compose.material.icons.filled.Shield +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalHapticFeedback +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.core.content.ContextCompat +import androidx.fragment.app.FragmentActivity +import com.ujwal.focusgram.core.security.EncryptedStorage +import com.ujwal.focusgram.core.ui.theme.AlertRed +import com.ujwal.focusgram.core.ui.theme.DarkCard +import com.ujwal.focusgram.core.ui.theme.PureBlack +import com.ujwal.focusgram.core.ui.theme.TextMuted +import com.ujwal.focusgram.core.ui.theme.TextSecondary +import kotlinx.coroutines.launch +import kotlin.math.roundToInt + +private val ChatLockAccent = Color(0xFF9D4EDD) +private val ChatLockAccentGlow = Color(0xFFC77DFF) +private val KeypadCardBg = Color(0xFF16161A) + +/** + * ChatLockScreen + * Bespoke, distinct hardware-backed PIN and Biometric security gate specifically + * tailored for locked Direct Messages and private conversations. + */ +@Composable +fun ChatLockScreen( + encryptedStorage: EncryptedStorage, + isBiometricAllowed: Boolean = true, + title: String = "Chat Protected", + subtitle: String = "Enter 4-digit PIN to view conversation", + customVerifyPin: ((String) -> Boolean)? = null, + onCancel: (() -> Unit)? = null, + onUnlockSuccess: () -> Unit +) { + val context = LocalContext.current + val haptic = LocalHapticFeedback.current + val coroutineScope = rememberCoroutineScope() + + var enteredPin by remember { mutableStateOf("") } + var errorMessage by remember { mutableStateOf(null) } + val shakeOffset = remember { Animatable(0f) } + + fun triggerBiometricPrompt() { + if (!isBiometricAllowed) return + var ctx = context + while (ctx is android.content.ContextWrapper) { + if (ctx is FragmentActivity) break + ctx = ctx.baseContext + } + val activity = ctx as? FragmentActivity ?: return + + val biometricManager = BiometricManager.from(activity) + val canAuth = biometricManager.canAuthenticate( + BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.BIOMETRIC_WEAK + ) + if (canAuth == BiometricManager.BIOMETRIC_SUCCESS) { + val executor = ContextCompat.getMainExecutor(activity) + val prompt = BiometricPrompt( + activity, + executor, + object : BiometricPrompt.AuthenticationCallback() { + override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { + super.onAuthenticationSucceeded(result) + onUnlockSuccess() + } + + override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { + super.onAuthenticationError(errorCode, errString) + if (errorCode != BiometricPrompt.ERROR_USER_CANCELED && + errorCode != BiometricPrompt.ERROR_NEGATIVE_BUTTON && + errorCode != BiometricPrompt.ERROR_CANCELED + ) { + errorMessage = errString.toString() + } + } + + override fun onAuthenticationFailed() { + super.onAuthenticationFailed() + errorMessage = "Biometric not recognized" + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + } + } + ) + + val promptInfo = BiometricPrompt.PromptInfo.Builder() + .setTitle(title) + .setSubtitle("Authenticate to view locked messages") + .setNegativeButtonText("Use PIN") + .build() + + prompt.authenticate(promptInfo) + } + } + + // Trigger Biometric only if explicitly allowed and configured + LaunchedEffect(isBiometricAllowed) { + if (isBiometricAllowed) { + triggerBiometricPrompt() + } + } + + fun verifyEnteredPin(pin: String) { + if (encryptedStorage.isLockedOut()) { + val remainingSec = encryptedStorage.getRemainingLockoutSeconds() + errorMessage = "Too many attempts. Locked out for ${remainingSec}s." + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + return + } + + val isValid = if (customVerifyPin != null) { + customVerifyPin(pin) + } else { + encryptedStorage.verifyPin(pin) + } + + if (isValid) { + errorMessage = null + haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) + onUnlockSuccess() + } else { + errorMessage = "Incorrect PIN" + enteredPin = "" + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + coroutineScope.launch { + shakeOffset.snapTo(0f) + shakeOffset.animateTo( + targetValue = 0f, + animationSpec = keyframes { + durationMillis = 400 + 0f at 0 + (-25f) at 50 + 25f at 100 + (-20f) at 150 + 20f at 200 + (-10f) at 250 + 10f at 300 + 0f at 400 + } + ) + } + } + } + + fun onDigitPressed(digit: String) { + if (enteredPin.length < 4) { + val newPin = enteredPin + digit + enteredPin = newPin + errorMessage = null + haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) + if (newPin.length == 4) { + verifyEnteredPin(newPin) + } + } + } + + fun onBackspacePressed() { + if (enteredPin.isNotEmpty()) { + enteredPin = enteredPin.dropLast(1) + errorMessage = null + haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove) + } + } + + Surface( + modifier = Modifier.fillMaxSize(), + color = PureBlack + ) { + Box( + modifier = Modifier + .fillMaxSize() + .background( + Brush.verticalGradient( + colors = listOf( + Color(0xFF0F0B17), + Color(0xFF060608), + PureBlack + ) + ) + ) + ) { + Column( + modifier = Modifier + .fillMaxSize() + .systemBarsPadding() + .padding(horizontal = 28.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + // Top Navigation Bar (Exit / Cancel) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 10.dp, bottom = 4.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + if (onCancel != null) { + IconButton( + onClick = onCancel, + modifier = Modifier + .size(36.dp) + .clip(CircleShape) + .background(Color.White.copy(alpha = 0.08f)) + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Back to inbox", + tint = Color.White, + modifier = Modifier.size(18.dp) + ) + } + } else { + Spacer(modifier = Modifier.size(36.dp)) + } + + // Subtle privacy status pill + Row( + modifier = Modifier + .clip(RoundedCornerShape(12.dp)) + .background(ChatLockAccent.copy(alpha = 0.15f)) + .border(0.5.dp, ChatLockAccent.copy(alpha = 0.3f), RoundedCornerShape(12.dp)) + .padding(horizontal = 10.dp, vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = Icons.Default.Shield, + contentDescription = null, + tint = ChatLockAccentGlow, + modifier = Modifier.size(13.dp) + ) + Spacer(modifier = Modifier.width(5.dp)) + Text( + text = "ENCRYPTED GATE", + fontSize = 10.sp, + fontWeight = FontWeight.Bold, + color = ChatLockAccentGlow, + letterSpacing = 0.8.sp + ) + } + + Spacer(modifier = Modifier.size(36.dp)) + } + + Spacer(modifier = Modifier.weight(0.7f)) + + // Chat Lock Shield Badge + Box( + modifier = Modifier + .size(72.dp) + .clip(CircleShape) + .background( + Brush.linearGradient( + colors = listOf( + ChatLockAccent.copy(alpha = 0.25f), + Color(0xFF3C096C).copy(alpha = 0.15f) + ) + ) + ) + .border(1.dp, ChatLockAccent.copy(alpha = 0.4f), CircleShape), + contentAlignment = Alignment.Center + ) { + Icon( + imageVector = Icons.Default.Lock, + contentDescription = "Lock", + tint = ChatLockAccentGlow, + modifier = Modifier.size(32.dp) + ) + } + + Spacer(modifier = Modifier.height(18.dp)) + + Text( + text = title, + style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.Bold), + color = Color.White, + textAlign = TextAlign.Center + ) + + Spacer(modifier = Modifier.height(6.dp)) + + Text( + text = subtitle, + style = MaterialTheme.typography.bodySmall, + color = TextSecondary, + textAlign = TextAlign.Center + ) + + Spacer(modifier = Modifier.height(28.dp)) + + // 4 PIN Dots with Smooth Glow & Shake Animation + Row( + modifier = Modifier + .offset { IntOffset(shakeOffset.value.roundToInt(), 0) } + .padding(vertical = 12.dp), + horizontalArrangement = Arrangement.spacedBy(18.dp) + ) { + for (i in 0 until 4) { + val isFilled = i < enteredPin.length + Box( + modifier = Modifier + .size(16.dp) + .clip(CircleShape) + .background( + if (isFilled) ChatLockAccentGlow else Color.White.copy(alpha = 0.18f) + ) + .border( + width = if (isFilled) 1.5.dp else 1.dp, + color = if (isFilled) Color.White else Color.White.copy(alpha = 0.1f), + shape = CircleShape + ) + ) + } + } + + // Error Message + if (errorMessage != null) { + Text( + text = errorMessage ?: "", + color = AlertRed, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + textAlign = TextAlign.Center, + modifier = Modifier.padding(top = 8.dp) + ) + } else { + Spacer(modifier = Modifier.height(24.dp)) + } + + Spacer(modifier = Modifier.weight(1.2f)) + + // Modern 3x4 Keypad + Column( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 20.dp), + verticalArrangement = Arrangement.spacedBy(14.dp) + ) { + // Only render "BIO" key if biometric is explicitly allowed & enrolled! + val bioKey = if (isBiometricAllowed) "BIO" else "" + val keypadRows = listOf( + listOf("1", "2", "3"), + listOf("4", "5", "6"), + listOf("7", "8", "9"), + listOf(bioKey, "0", "DEL") + ) + + for (row in keypadRows) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + for (key in row) { + KeypadCell( + key = key, + onDigit = { onDigitPressed(it) }, + onBackspace = { onBackspacePressed() }, + onBiometric = { triggerBiometricPrompt() } + ) + } + } + } + } + } + } + } +} + +@Composable +private fun KeypadCell( + key: String, + onDigit: (String) -> Unit, + onBackspace: () -> Unit, + onBiometric: () -> Unit +) { + Box( + modifier = Modifier + .size(72.dp) + .clip(CircleShape) + .background(if (key.isNotBlank()) KeypadCardBg else Color.Transparent) + .clickable(enabled = key.isNotBlank()) { + when (key) { + "DEL" -> onBackspace() + "BIO" -> onBiometric() + else -> onDigit(key) + } + }, + contentAlignment = Alignment.Center + ) { + when (key) { + "DEL" -> Icon( + imageVector = Icons.AutoMirrored.Filled.Backspace, + contentDescription = "Delete", + tint = Color.White.copy(alpha = 0.75f), + modifier = Modifier.size(22.dp) + ) + "BIO" -> Icon( + imageVector = Icons.Default.Fingerprint, + contentDescription = "Biometric", + tint = ChatLockAccentGlow, + modifier = Modifier.size(28.dp) + ) + "" -> { + // Empty spacer cell so layout remains symmetrical without any biometric icon + } + else -> Text( + text = key, + fontSize = 25.sp, + fontWeight = FontWeight.Medium, + color = Color.White + ) + } + } +} diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/history/ReelsHistoryScreen.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/history/ReelsHistoryScreen.kt index 2171041..edaca7d 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/history/ReelsHistoryScreen.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/history/ReelsHistoryScreen.kt @@ -84,11 +84,12 @@ fun ReelsHistoryScreen( val allReels by reelHistory.items.collectAsState() val reels = remember(allReels, searchQuery) { + val deduplicated = allReels.distinctBy { it.code.ifBlank { it.url } } if (searchQuery.isBlank()) { - allReels + deduplicated } else { val q = searchQuery.trim().lowercase() - allReels.filter { + deduplicated.filter { it.author.lowercase().contains(q) || it.caption.lowercase().contains(q) || it.code.lowercase().contains(q) diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/navigation/NativeBottomNavBar.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/navigation/NativeBottomNavBar.kt index f105676..f9dab43 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/navigation/NativeBottomNavBar.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/navigation/NativeBottomNavBar.kt @@ -149,7 +149,8 @@ fun NativeBottomNavBar( } else { isInDirect } - val isAuth = isAuthPage || !isAuthenticated || lowerUrl.contains("/accounts") || lowerUrl.contains("/login") || lowerUrl.contains("/signup") + val isExplicitAuthRoute = (lowerUrl.contains("/accounts") && !lowerUrl.contains("/accounts/edit")) || lowerUrl.contains("/login") || lowerUrl.contains("/signup") + val isAuth = isAuthPage || isExplicitAuthRoute val isVisible = !isAuth && !isImeVisible && !shouldHideInDirect && !isWebInputFocused && !isModalActive && islandMode != IslandMode.HIDDEN // Real-time animated color palette matching Instagram's web theme diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/settings/SettingsScreen.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/settings/SettingsScreen.kt index 55d1f30..14f72fc 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/settings/SettingsScreen.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/settings/SettingsScreen.kt @@ -38,6 +38,18 @@ import kotlinx.coroutines.delay import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowForwardIos +import androidx.compose.material.icons.automirrored.filled.Chat +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.Lock +import android.widget.Toast +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.material3.CircularProgressIndicator +import com.ujwal.focusgram.core.utils.AppIconManager +import com.ujwal.focusgram.core.utils.HistoricalIconManager +import com.ujwal.focusgram.core.security.EncryptedStorage import androidx.compose.material.icons.automirrored.filled.OpenInNew import androidx.compose.material.icons.filled.Block import androidx.compose.material.icons.filled.Close @@ -113,9 +125,11 @@ enum class SettingsSubpage { GUARDRAILS, EXTRAS, APPEARANCE, + CHOOSE_APP_ICON, NOTIFICATIONS, GHOST, - LICENSES + LICENSES, + CHAT_SECURITY } /** @@ -127,6 +141,7 @@ enum class SettingsSubpage { @Composable fun SettingsScreen( repository: SettingsRepository, + inputSettings: FocusSettings? = null, onBack: () -> Unit, onNavigateReelsHistory: () -> Unit, onNavigateScreenTime: () -> Unit, @@ -138,9 +153,12 @@ fun SettingsScreen( reelHistory: ReelHistory? = null, currentSubpage: SettingsSubpage = SettingsSubpage.MAIN, onSubpageChange: (SettingsSubpage) -> Unit = {}, + encryptedStorage: EncryptedStorage? = null, + onNavigateChatPinSetup: () -> Unit = {}, modifier: Modifier = Modifier ) { - val settings by repository.settingsFlow.collectAsState(initial = FocusSettings()) + val collectedSettings by repository.settingsFlow.collectAsState(initial = inputSettings ?: FocusSettings()) + val settings = inputSettings ?: collectedSettings val scope = rememberCoroutineScope() val context = LocalContext.current @@ -165,7 +183,9 @@ fun SettingsScreen( // Intercept back presses: go back to MAIN subpage first, or pop screen BackHandler { - if (activeSubpage != SettingsSubpage.MAIN) { + if (activeSubpage == SettingsSubpage.CHOOSE_APP_ICON) { + setSubpage(SettingsSubpage.APPEARANCE) + } else if (activeSubpage != SettingsSubpage.MAIN) { setSubpage(SettingsSubpage.MAIN) } else { onBack() @@ -380,7 +400,9 @@ fun SettingsScreen( verticalAlignment = Alignment.CenterVertically ) { IconButton(onClick = { - if (activeSubpage != SettingsSubpage.MAIN) { + if (activeSubpage == SettingsSubpage.CHOOSE_APP_ICON) { + setSubpage(SettingsSubpage.APPEARANCE) + } else if (activeSubpage != SettingsSubpage.MAIN) { setSubpage(SettingsSubpage.MAIN) } else { onBack() @@ -399,9 +421,11 @@ fun SettingsScreen( SettingsSubpage.GUARDRAILS -> "Time Control & Guardrails" SettingsSubpage.EXTRAS -> "Extras" SettingsSubpage.APPEARANCE -> "Appearance" + SettingsSubpage.CHOOSE_APP_ICON -> "Choose App Icon" SettingsSubpage.NOTIFICATIONS -> "Privacy & Notifications" SettingsSubpage.GHOST -> "Ghost Mode" SettingsSubpage.LICENSES -> "Open Source & Credits" + SettingsSubpage.CHAT_SECURITY -> "Chat Security & DM Lock" }, color = IOSTextPrimary, fontSize = 17.sp, @@ -454,7 +478,18 @@ fun SettingsScreen( ) } SettingsSubpage.APPEARANCE -> { - AppearanceSubpage(repository = repository, settings = settings) + AppearanceSubpage( + repository = repository, + settings = settings, + onNavigateChooseIcon = { setSubpage(SettingsSubpage.CHOOSE_APP_ICON) } + ) + } + SettingsSubpage.CHOOSE_APP_ICON -> { + ChooseAppIconSubpage( + repository = repository, + settings = settings, + onBack = { setSubpage(SettingsSubpage.APPEARANCE) } + ) } SettingsSubpage.NOTIFICATIONS -> { NotificationsSubpage(repository = repository, settings = settings) @@ -465,6 +500,14 @@ fun SettingsScreen( SettingsSubpage.LICENSES -> { LicensesSubpage() } + SettingsSubpage.CHAT_SECURITY -> { + ChatSecuritySubpage( + repository = repository, + settings = settings, + encryptedStorage = encryptedStorage, + onNavigateChatPinSetup = onNavigateChatPinSetup + ) + } } } } @@ -713,14 +756,26 @@ private fun MainSettingsContent( item { IOSSectionTitle(title = "SECURITY & PRIVACY") IOSGroupedCard { + val isBiometricsActive = settings.appLockEnabled && settings.biometricEnabled IOSSettingsRow( title = "App Lock", - subtitle = if (settings.appLockEnabled) "PIN & Biometrics enabled" else "Off", - icon = Icons.Default.Fingerprint, - iconBgColor = IOSGreen, + subtitle = when { + !settings.appLockEnabled -> "Off" + isBiometricsActive -> "PIN & Biometrics enabled" + else -> "4-Digit PIN enabled" + }, + icon = if (isBiometricsActive) Icons.Default.Fingerprint else Icons.Default.Lock, + iconBgColor = if (isBiometricsActive) IOSGreen else IOSOrange, trailingText = if (settings.appLockEnabled) "Enabled" else "Off", onClick = onNavigateAppLock ) + IOSSettingsRow( + title = "Chat Security & DM Lock", + subtitle = if (settings.chatLockAll || settings.lockedChatIds.isNotEmpty()) "Active ยท Locked conversations" else "Lock inbox & chats with PIN/Biometrics", + icon = Icons.AutoMirrored.Filled.Chat, + iconBgColor = IOSBlue, + onClick = { onNavigateSubpage(SettingsSubpage.CHAT_SECURITY) } + ) IOSSettingsRow( title = "Ghost Mode (Stealth)", subtitle = if (settings.ghostModeEnabled) "Active ยท Hiding story & DM seen" else "Off", @@ -896,7 +951,7 @@ private fun FocusModeSubpage( IOSGroupedCard { IOSSettingsRow( title = "Block Video Autoplay", - subtitle = "Stop videos and reels from playing automatically", + subtitle = "Stop videos and reels from playing automatically (click audio icon to play)", icon = Icons.Default.PlayArrow, iconBgColor = IOSBlue, checked = settings.noAutoplay, @@ -1603,7 +1658,8 @@ private fun ExtrasSubpage( @Composable private fun AppearanceSubpage( repository: SettingsRepository, - settings: FocusSettings + settings: FocusSettings, + onNavigateChooseIcon: () -> Unit ) { val scope = rememberCoroutineScope() @@ -1627,6 +1683,320 @@ private fun AppearanceSubpage( } } + item { + Spacer(modifier = Modifier.height(16.dp)) + IOSSectionTitle(title = "APP ICON") + IOSGroupedCard { + IOSSettingsRow( + title = "Custom Icons", + subtitle = "Enable custom launcher and era icons", + icon = Icons.Default.Palette, + iconBgColor = IOSPurple, + checked = settings.customIconsEnabled, + onCheckedChange = { isChecked -> + scope.launch { repository.setCustomIconsEnabled(isChecked) } + }, + showDivider = settings.customIconsEnabled + ) + if (settings.customIconsEnabled) { + val activeOption = AppIconManager.IconOption.fromId(settings.appIcon) + IOSSettingsRow( + title = "Choose App Icon", + subtitle = "Select launcher icon style", + icon = Icons.Default.Palette, + iconBgColor = IOSBlue, + trailingText = activeOption.displayName, + onClick = onNavigateChooseIcon, + showDivider = false + ) + } + } + } + + item { + Spacer(modifier = Modifier.height(40.dp)) + } + } +} + +// โ”€โ”€โ”€ CHOOSE APP ICON SUBPAGE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +@Composable +private fun ChooseAppIconSubpage( + repository: SettingsRepository, + settings: FocusSettings, + onBack: () -> Unit +) { + val scope = rememberCoroutineScope() + val context = LocalContext.current + val currentIconId = settings.appIcon.ifEmpty { "default" } + + val coreOptions = remember { + AppIconManager.IconOption.values().filter { it.category == "Core" } + } + val originalOptions = remember { + AppIconManager.IconOption.values().filter { it.category == "Originals" } + } + val redesignOptions = remember { + AppIconManager.IconOption.values().filter { it.category == "Redesigns" } + } + + LazyColumn( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp) + ) { + // Section 1: Core System Icons + item { + IOSSectionTitle(title = "CORE ICONS") + IOSGroupedCard { + coreOptions.forEachIndexed { index, option -> + val isSelected = currentIconId == option.id + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { + scope.launch { + repository.setAppIcon(option.id) + AppIconManager.setAppIcon(context, option.id) + } + } + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + val iconBitmap = remember(option.iconRes) { + AppIconManager.getIconBitmap(context, option.iconRes) + } + Box( + modifier = Modifier + .size(50.dp) + .clip(RoundedCornerShape(12.dp)) + .border( + width = if (isSelected) 2.dp else 1.dp, + color = if (isSelected) IOSBlue else Color.White.copy(alpha = 0.15f), + shape = RoundedCornerShape(12.dp) + ), + contentAlignment = Alignment.Center + ) { + if (iconBitmap != null) { + androidx.compose.foundation.Image( + bitmap = iconBitmap.asImageBitmap(), + contentDescription = option.displayName, + modifier = Modifier.fillMaxSize() + ) + } + } + + Spacer(modifier = Modifier.width(14.dp)) + + Column(modifier = Modifier.weight(1f)) { + Text( + text = option.displayName, + fontSize = 16.sp, + fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal, + color = IOSTextPrimary + ) + Text( + text = option.subtitle, + fontSize = 12.sp, + color = IOSTextSecondary, + lineHeight = 16.sp + ) + } + + if (isSelected) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = "Active", + tint = IOSBlue, + modifier = Modifier.size(20.dp) + ) + } + } + + if (index < coreOptions.size - 1) { + androidx.compose.material3.HorizontalDivider( + color = IOSDivider, + thickness = 0.5.dp, + modifier = Modifier.padding(start = 80.dp) + ) + } + } + } + } + + // Section 2: Originals + item { + Spacer(modifier = Modifier.height(16.dp)) + IOSSectionTitle(title = "ORIGINALS") + IOSGroupedCard { + originalOptions.forEachIndexed { index, option -> + val isSelected = currentIconId == option.id + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { + scope.launch { + repository.setAppIcon(option.id) + AppIconManager.setAppIcon(context, option.id) + } + } + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + val iconBitmap = remember(option.iconRes) { + AppIconManager.getIconBitmap(context, option.iconRes) + } + Box( + modifier = Modifier + .size(50.dp) + .clip(RoundedCornerShape(12.dp)) + .border( + width = if (isSelected) 2.dp else 1.dp, + color = if (isSelected) IOSBlue else Color.White.copy(alpha = 0.15f), + shape = RoundedCornerShape(12.dp) + ), + contentAlignment = Alignment.Center + ) { + if (iconBitmap != null) { + androidx.compose.foundation.Image( + bitmap = iconBitmap.asImageBitmap(), + contentDescription = option.displayName, + modifier = Modifier.fillMaxSize() + ) + } + } + + Spacer(modifier = Modifier.width(14.dp)) + + Column(modifier = Modifier.weight(1f)) { + Text( + text = option.displayName, + fontSize = 16.sp, + fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal, + color = IOSTextPrimary + ) + Text( + text = option.subtitle, + fontSize = 12.sp, + color = IOSTextSecondary, + lineHeight = 16.sp + ) + } + + if (isSelected) { + Spacer(modifier = Modifier.width(8.dp)) + Icon( + imageVector = Icons.Default.Check, + contentDescription = "Active", + tint = IOSBlue, + modifier = Modifier.size(20.dp) + ) + } + } + + if (index < originalOptions.size - 1) { + androidx.compose.material3.HorizontalDivider( + color = IOSDivider, + thickness = 0.5.dp, + modifier = Modifier.padding(start = 80.dp) + ) + } + } + } + } + + // Section 3: Redesigns (alt-logos) + item { + Spacer(modifier = Modifier.height(16.dp)) + IOSSectionTitle(title = "REDESIGNS") + IOSGroupedCard { + redesignOptions.forEachIndexed { index, option -> + val isSelected = currentIconId == option.id + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { + scope.launch { + repository.setAppIcon(option.id) + AppIconManager.setAppIcon(context, option.id) + } + } + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + val iconBitmap = remember(option.iconRes) { + AppIconManager.getIconBitmap(context, option.iconRes) + } + Box( + modifier = Modifier + .size(50.dp) + .clip(RoundedCornerShape(12.dp)) + .border( + width = if (isSelected) 2.dp else 1.dp, + color = if (isSelected) IOSBlue else Color.White.copy(alpha = 0.15f), + shape = RoundedCornerShape(12.dp) + ), + contentAlignment = Alignment.Center + ) { + if (iconBitmap != null) { + androidx.compose.foundation.Image( + bitmap = iconBitmap.asImageBitmap(), + contentDescription = option.displayName, + modifier = Modifier.fillMaxSize() + ) + } + } + + Spacer(modifier = Modifier.width(14.dp)) + + Column(modifier = Modifier.weight(1f)) { + Text( + text = option.displayName, + fontSize = 16.sp, + fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Normal, + color = IOSTextPrimary + ) + Text( + text = option.subtitle, + fontSize = 12.sp, + color = IOSTextSecondary, + lineHeight = 16.sp + ) + } + + if (isSelected) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = "Active", + tint = IOSBlue, + modifier = Modifier.size(20.dp) + ) + } + } + + if (index < redesignOptions.size - 1) { + androidx.compose.material3.HorizontalDivider( + color = IOSDivider, + thickness = 0.5.dp, + modifier = Modifier.padding(start = 80.dp) + ) + } + } + } + } + + item { + Spacer(modifier = Modifier.height(12.dp)) + Text( + text = "Core, Original, and Redesign icons replace the application icon system-wide across Home Screen, App Drawer, and Recents.", + color = Color(0xFF8E8E93), + fontSize = 12.sp, + lineHeight = 16.sp, + modifier = Modifier.padding(horizontal = 16.dp) + ) + } + item { Spacer(modifier = Modifier.height(40.dp)) } @@ -1859,3 +2229,231 @@ private fun LicensesSubpage() { } } } + +// โ”€โ”€โ”€ CHAT SECURITY & DM PRIVACY SUBPAGE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +@Composable +private fun ChatSecuritySubpage( + repository: SettingsRepository, + settings: FocusSettings, + encryptedStorage: EncryptedStorage?, + onNavigateChatPinSetup: () -> Unit +) { + val scope = rememberCoroutineScope() + val context = LocalContext.current + var showLockModeModal by remember { mutableStateOf(false) } + + val lockModeOptions = remember { + listOf( + "off" to "Off", + "individual" to "Individual DMs", + "whole_dm" to "Whole DM" + ) + } + val currentLockModeIdx = remember(settings.chatLockMode) { + lockModeOptions.indexOfFirst { it.first == settings.chatLockMode }.coerceAtLeast(0) + } + val lockModeLabel = when (settings.chatLockMode) { + "whole_dm" -> "Whole DM" + "individual" -> "Individual DMs" + else -> "Off" + } + val lockModeSubtitle = when (settings.chatLockMode) { + "whole_dm" -> "Require authentication to open your DM inbox and any chat" + "individual" -> "Protect selected chats individually with lock button in header" + else -> "Direct messages protection disabled" + } + + LazyColumn( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp) + ) { + item { + IOSSectionTitle(title = "DIRECT MESSAGE PRIVACY") + IOSGroupedCard { + IOSSettingsRow( + title = "Messages Lock Mode", + subtitle = lockModeSubtitle, + trailingText = lockModeLabel, + icon = Icons.AutoMirrored.Filled.Chat, + iconBgColor = IOSBlue, + onClick = { showLockModeModal = true }, + showDivider = false + ) + } + } + + item { + IOSSectionTitle(title = "AUTHENTICATION METHOD") + IOSGroupedCard { + IOSSettingsRow( + title = "Biometric Unlock", + subtitle = "Use fingerprint or face recognition for chat locks", + icon = Icons.Default.Fingerprint, + iconBgColor = IOSGreen, + checked = settings.chatBiometricEnabled, + onCheckedChange = { scope.launch { repository.setChatBiometricEnabled(it) } } + ) + IOSSettingsRow( + title = "Use Separate Chat PIN", + subtitle = if (settings.useSeparateChatPin) { + if (encryptedStorage?.hasChatPin() == true) "Dedicated Chat PIN configured" else "Tap below to set dedicated PIN" + } else { + "Uses the main App Lock PIN" + }, + icon = Icons.Default.Lock, + iconBgColor = IOSOrange, + checked = settings.useSeparateChatPin, + onCheckedChange = { isChecked -> + scope.launch { repository.setUseSeparateChatPin(isChecked) } + if (isChecked && encryptedStorage?.hasChatPin() != true) { + onNavigateChatPinSetup() + } + }, + showDivider = settings.useSeparateChatPin + ) + if (settings.useSeparateChatPin) { + IOSSettingsRow( + title = if (encryptedStorage?.hasChatPin() == true) "Change Chat PIN" else "Set Chat PIN", + subtitle = "Configure dedicated 4-digit PIN for chats", + icon = Icons.Default.Lock, + iconBgColor = Color(0xFF636366), + onClick = onNavigateChatPinSetup, + showDivider = false + ) + } + } + } + + item { + IOSSectionTitle(title = "LOCKED CONVERSATIONS") + IOSGroupedCard { + if (settings.lockedChatIds.isEmpty()) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 14.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "No individual conversations locked yet. Open any chat on Instagram and tap the Lock icon in the header to protect it.", + color = IOSTextSecondary, + fontSize = 13.sp, + lineHeight = 18.sp + ) + } + } else { + settings.lockedChatIds.toList().forEachIndexed { index, id -> + val username = settings.lockedChatUsernames[id] + val displayTitle = if (!username.isNullOrBlank()) { + "@${username.removePrefix("@")}" + } else if (!id.all { it.isDigit() }) { + "@${id.removePrefix("@")}" + } else { + "Conversation (@$id)" + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Box( + modifier = Modifier + .size(36.dp) + .clip(CircleShape) + .background(Color(0xFF2C2C2E)), + contentAlignment = Alignment.Center + ) { + Icon( + imageVector = Icons.Default.Lock, + contentDescription = null, + tint = IOSPurple, + modifier = Modifier.size(18.dp) + ) + } + Spacer(modifier = Modifier.width(12.dp)) + Column(modifier = Modifier.weight(1f)) { + Text( + text = displayTitle, + color = IOSTextPrimary, + fontSize = 15.sp, + fontWeight = FontWeight.Medium + ) + Text( + text = if (!username.isNullOrBlank()) "Protected direct message" else if (!id.all { it.isDigit() }) "Protected direct message" else "Direct conversation ยท $id", + color = IOSTextSecondary, + fontSize = 11.sp + ) + } + IconButton( + onClick = { + scope.launch { repository.removeLockedChatId(id) } + Toast.makeText(context, "Unlocked $displayTitle", Toast.LENGTH_SHORT).show() + }, + modifier = Modifier.size(32.dp) + ) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = "Remove lock", + tint = IOSRed, + modifier = Modifier.size(18.dp) + ) + } + } + if (index < settings.lockedChatIds.size - 1) { + androidx.compose.material3.HorizontalDivider( + color = IOSDivider, + thickness = 0.5.dp, + modifier = Modifier.padding(start = 64.dp) + ) + } + } + } + } + + Spacer(modifier = Modifier.height(10.dp)) + IOSGroupedCard { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = Icons.Default.Info, + contentDescription = null, + tint = IOSBlue, + modifier = Modifier.size(20.dp) + ) + Spacer(modifier = Modifier.width(12.dp)) + Text( + text = "To lock a conversation, open the chat in Direct Messages and tap the Lock icon next to the conversation details (i) in the top bar.", + color = IOSTextSecondary, + fontSize = 12.sp, + lineHeight = 16.sp + ) + } + } + } + + item { + Spacer(modifier = Modifier.height(40.dp)) + } + } + + if (showLockModeModal) { + WheelPickerModalDialog( + title = "Messages Lock Mode", + subtitle = "Choose lock protection mode for Instagram direct messages", + options = lockModeOptions, + initialIndex = currentLockModeIdx, + onDismiss = { showLockModeModal = false }, + onConfirm = { option -> + scope.launch { repository.setChatLockMode(option.first) } + }, + labelProvider = { it.second } + ) + } +} diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/wellness/AdsterraAdScreen.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/wellness/AdsterraAdScreen.kt index d4afa44..28804c5 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/wellness/AdsterraAdScreen.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/feature/wellness/AdsterraAdScreen.kt @@ -47,6 +47,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -152,9 +153,11 @@ fun AdsterraAdScreen( onRewardClaimed: () -> Unit, onCancel: () -> Unit ) { - var timerCycle by remember { mutableIntStateOf(0) } - var elapsedSeconds by remember { mutableIntStateOf(0) } - var adsClicked by remember { mutableIntStateOf(0) } + var timerCycle by rememberSaveable { mutableIntStateOf(0) } + var elapsedSeconds by rememberSaveable { mutableIntStateOf(0) } + var adsClicked by rememberSaveable { mutableIntStateOf(0) } + var lastClickedUrl by rememberSaveable { mutableStateOf("") } + var lastClickTime by rememberSaveable { mutableStateOf(0L) } var webViewRef by remember { mutableStateOf(null) } val isSettingToggle = sessionType == "setting_toggle" @@ -162,9 +165,17 @@ fun AdsterraAdScreen( val bothClicked = adsClicked >= 2 val isComplete = if (isSettingToggle) timerDone else (timerDone && bothClicked) - // 20s Timer Loop - restarts cleanly on timerCycle increment + // Ensure clean countdown and state when entering a setting toggle session + LaunchedEffect(sessionType) { + if (isSettingToggle) { + elapsedSeconds = 0 + adsClicked = 0 + timerCycle++ + } + } + + // 20s Timer Loop - continues cleanly from saved elapsedSeconds without resetting LaunchedEffect(timerCycle) { - elapsedSeconds = 0 while (elapsedSeconds < requiredSeconds) { delay(1000L) elapsedSeconds++ @@ -308,25 +319,43 @@ fun AdsterraAdScreen( } setBackgroundColor(0xFF111111.toInt()) + fun handleAdClick(url: String): Boolean { + val clean = url.trim() + if (clean.isNotBlank() && !clean.contains("effectivecpmnetwork.com") && !clean.contains("highperformanceformat.com") && !clean.startsWith("about:") && !clean.startsWith("data:")) { + val now = System.currentTimeMillis() + if (clean != lastClickedUrl || now - lastClickTime > 1500L) { + lastClickedUrl = clean + lastClickTime = now + if (adsClicked < 2) { + adsClicked++ + } + } + try { + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(clean)).apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + ctx.startActivity(browserIntent) + } catch (_: Exception) {} + return true + } + return false + } + webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading( view: WebView?, request: WebResourceRequest? ): Boolean { val url = request?.url?.toString() ?: "" - if (url.isNotBlank() && !url.contains("effectivecpmnetwork.com") && !url.contains("highperformanceformat.com") && !url.startsWith("about:")) { - if (adsClicked < 2) { - adsClicked++ - } - try { - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ctx.startActivity(browserIntent) - } catch (_: Exception) {} - return true - } - return false + return handleAdClick(url) + } + + @Deprecated("Deprecated in Java") + override fun shouldOverrideUrlLoading( + view: WebView?, + url: String? + ): Boolean { + return handleAdClick(url ?: "") } } @@ -339,25 +368,34 @@ fun AdsterraAdScreen( ): Boolean { val transport = resultMsg?.obj as? WebView.WebViewTransport val tempWebView = WebView(ctx).apply { + settings.javaScriptEnabled = true + settings.domStorageEnabled = true + settings.setSupportMultipleWindows(true) webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading( view: WebView?, request: WebResourceRequest? ): Boolean { val url = request?.url?.toString() ?: "" - if (url.isNotBlank() && !url.startsWith("about:")) { - if (adsClicked < 2) { - adsClicked++ + return handleAdClick(url) + } + + @Deprecated("Deprecated in Java") + override fun shouldOverrideUrlLoading( + view: WebView?, + url: String? + ): Boolean { + return handleAdClick(url ?: "") + } + + override fun onPageStarted(view: WebView?, url: String?, favicon: android.graphics.Bitmap?) { + super.onPageStarted(view, url, favicon) + val u = url ?: "" + if (u.isNotBlank() && !u.startsWith("about:") && !u.startsWith("data:")) { + if (!u.contains("effectivecpmnetwork.com") && !u.contains("highperformanceformat.com")) { + handleAdClick(u) } - try { - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - ctx.startActivity(browserIntent) - } catch (_: Exception) {} - return true } - return false } } } @@ -383,7 +421,11 @@ fun AdsterraAdScreen( ) { // Primary Claim Button: Apple Style Pill Button Button( - onClick = onRewardClaimed, + onClick = { + elapsedSeconds = 0 + adsClicked = 0 + onRewardClaimed() + }, enabled = isComplete, modifier = Modifier .fillMaxWidth() @@ -419,7 +461,10 @@ fun AdsterraAdScreen( Button( onClick = { timerCycle++ + elapsedSeconds = 0 adsClicked = 0 + lastClickedUrl = "" + lastClickTime = 0L webViewRef?.loadDataWithBaseURL("https://effectivecpmnetwork.com", AD_HTML, "text/html", "UTF-8", null) }, modifier = Modifier diff --git a/Ported/app/src/main/kotlin/com/ujwal/focusgram/ui/FocusGramApp.kt b/Ported/app/src/main/kotlin/com/ujwal/focusgram/ui/FocusGramApp.kt index 507c9da..79e7c11 100644 --- a/Ported/app/src/main/kotlin/com/ujwal/focusgram/ui/FocusGramApp.kt +++ b/Ported/app/src/main/kotlin/com/ujwal/focusgram/ui/FocusGramApp.kt @@ -35,6 +35,7 @@ import com.ujwal.focusgram.core.utils.MediaDownloadHelper import com.ujwal.focusgram.feature.screentime.ScreenTimeService import androidx.compose.ui.draw.blur import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.isSystemInDarkTheme @@ -42,9 +43,28 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Lock +import androidx.compose.material.icons.outlined.Lock +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import android.widget.Toast +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.statusBarsPadding @@ -61,6 +81,7 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment @@ -89,6 +110,7 @@ import com.ujwal.focusgram.core.ui.theme.PureBlack import com.ujwal.focusgram.feature.applock.AppLockScreen import com.ujwal.focusgram.feature.applock.AppLockSettingsPage import com.ujwal.focusgram.feature.applock.AppLockSetupScreen +import com.ujwal.focusgram.feature.applock.ChatLockScreen import com.ujwal.focusgram.feature.diagnostics.DebugMenuScreen import com.ujwal.focusgram.feature.history.ReelsHistoryRepository import com.ujwal.focusgram.feature.history.ReelsHistoryScreen @@ -119,10 +141,17 @@ enum class AppDestination { GUARDRAILS, APP_LOCK_SETUP, APP_LOCK_SETTINGS, + CHAT_LOCK_SETUP, DEBUG_MENU, ADSTERRA_REWARDED } +data class PendingChatUnlock( + val threadId: String, + val username: String?, + val targetUrl: String? +) + /** * FocusGramApp * Primary Jetpack Compose application composable. @@ -165,16 +194,111 @@ fun FocusGramApp() { val settings by settingsRepository.settingsFlow.collectAsState(initial = initialSettings) val currentUrl by sessionManager.currentUrl.collectAsState() var isAppInForeground by remember { mutableStateOf(true) } - var destination by remember { mutableStateOf(AppDestination.MAIN_WEBVIEW) } + var destination by rememberSaveable { mutableStateOf(AppDestination.MAIN_WEBVIEW) } val isViewingReels = destination == AppDestination.MAIN_WEBVIEW && currentUrl.lowercase().contains("/reel") val hasPin = remember { encryptedStorage.hasPin() } - var isAppUnlocked by remember { mutableStateOf(false) } + var isAppUnlocked by rememberSaveable { mutableStateOf(false) } val shouldShowLock = settings.appLockEnabled && hasPin && !isAppUnlocked - var hasPassedSessionPicker by remember { mutableStateOf(false) } - var hasPassedBreathGate by remember { mutableStateOf(!initialSettings.showBreathGate || initialSettings.breathGateSeconds <= 0) } - var hasPassedEffortFriction by remember { mutableStateOf(!initialSettings.effortFrictionEnabled || initialSettings.wordChallengeCount <= 0) } + + // Direct Messages & Chat Lock Evaluation + val threadToUsernameMap = remember { androidx.compose.runtime.mutableStateMapOf>() } + var unlockedChatThreadIds by remember { mutableStateOf(emptySet()) } + var isDirectAllUnlocked by remember { mutableStateOf(false) } + var pendingUnlockChat by remember { mutableStateOf(null) } + + LaunchedEffect(extensionManager) { + extensionManager.onThreadUsernameMapped = { threadId, usernames -> + val cleanThreadId = threadId.lowercase().trim() + val existing = threadToUsernameMap[cleanThreadId] ?: emptySet() + threadToUsernameMap[cleanThreadId] = existing + usernames.map { it.lowercase().trim().removePrefix("@") } + scope.launch { + usernames.firstOrNull()?.let { user -> + settingsRepository.mapThreadUsername(threadId, user) + } + } + } + extensionManager.onRequestUnlockChat = { threadId, username, targetUrl -> + val cleanThreadId = threadId.lowercase().trim() + val cleanUser = username?.lowercase()?.trim()?.removePrefix("@") + ?: threadToUsernameMap[cleanThreadId]?.firstOrNull() + ?: settings.lockedChatUsernames[cleanThreadId] + pendingUnlockChat = PendingChatUnlock(cleanThreadId, cleanUser, targetUrl) + } + extensionManager.onToggleChatLock = { threadId, username -> + scope.launch { + val isNowLocked = settingsRepository.toggleLockedChat(threadId, username) + val label = if (!username.isNullOrBlank()) "@$username" else "Conversation" + val msg = if (isNowLocked) "Locked $label" else "Unlocked $label" + android.widget.Toast.makeText(context, msg, android.widget.Toast.LENGTH_SHORT).show() + } + } + } + + val currentUri = remember(currentUrl) { try { Uri.parse(currentUrl) } catch (_: Exception) { null } } + val currentPath = currentUri?.path?.lowercase() ?: "" + val isDirectRoute = currentPath.startsWith("/direct") + val currentThreadId = remember(currentPath) { + if (currentPath.startsWith("/direct/t/")) { + currentPath.removePrefix("/direct/t/").trim('/').split('/').firstOrNull()?.trim() + } else null + } + + var activeThreadId by remember { mutableStateOf(null) } + LaunchedEffect(currentThreadId) { + if (activeThreadId != null && activeThreadId != currentThreadId) { + val closedThreadId = activeThreadId!! + unlockedChatThreadIds = unlockedChatThreadIds - closedThreadId + extensionManager.notifyChatLocked(closedThreadId) + sessionManager.userScriptManager?.evaluate(sessionManager.session, """ + if (window.__fgUnlockedThreads && Array.isArray(window.__fgUnlockedThreads)) { + window.__fgUnlockedThreads = window.__fgUnlockedThreads.filter(function(id) { return id !== '${closedThreadId.lowercase().trim()}'; }); + } + window.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { + detail: { unlockedThreads: window.__fgUnlockedThreads || [] } + })); + """) + } + activeThreadId = currentThreadId + } + + val isChatLockActive = remember( + currentUrl, + currentPath, + currentThreadId, + settings, + unlockedChatThreadIds, + isDirectAllUnlocked, + threadToUsernameMap.size, + pendingUnlockChat, + settings.lockedChatUsernames.size + ) { + if (pendingUnlockChat != null) return@remember true + if (!isDirectRoute) return@remember false + if (settings.chatLockMode == "off") return@remember false + if (settings.chatLockMode == "whole_dm" || settings.chatLockAll) { + if (isDirectAllUnlocked) return@remember false + return@remember true + } + if (currentThreadId != null) { + if (unlockedChatThreadIds.contains(currentThreadId)) return@remember false + val associatedUsers = threadToUsernameMap[currentThreadId] ?: emptySet() + val mappedName = settings.lockedChatUsernames[currentThreadId] + val isLocked = settings.lockedChatIds.any { lockedId -> + val clean = lockedId.trim().lowercase().removePrefix("@") + clean.equals(currentThreadId, ignoreCase = true) || + currentUrl.contains(clean, ignoreCase = true) || + associatedUsers.any { it.equals(clean, ignoreCase = true) } || + (!mappedName.isNullOrBlank() && clean.equals(mappedName.lowercase().trim().removePrefix("@"), ignoreCase = true)) + } + return@remember isLocked + } + false + } + var hasPassedSessionPicker by rememberSaveable { mutableStateOf(false) } + var hasPassedBreathGate by rememberSaveable { mutableStateOf(!initialSettings.showBreathGate || initialSettings.breathGateSeconds <= 0) } + var hasPassedEffortFriction by rememberSaveable { mutableStateOf(!initialSettings.effortFrictionEnabled || initialSettings.wordChallengeCount <= 0) } val lastSessionEndTimestamp by settingsRepository.lastSessionEndTimestampFlow.collectAsState(initial = 0L) - var hasPassedCooldownGate by remember { mutableStateOf(false) } + var hasPassedCooldownGate by rememberSaveable { mutableStateOf(false) } val dateFormat = remember { SimpleDateFormat("yyyy-MM-dd", Locale.US) } val today = remember { dateFormat.format(Date()) } @@ -193,6 +317,8 @@ fun FocusGramApp() { } var isWebInputFocused by remember { mutableStateOf(false) } + var isBioFocused by remember { mutableStateOf(false) } + var selectedBioStyle by remember { mutableStateOf("bold") } var isModalActive by remember { mutableStateOf(false) } var isUserAuthenticated by remember { mutableStateOf(false) } var isAuthPage by remember { mutableStateOf(false) } @@ -207,12 +333,14 @@ fun FocusGramApp() { var settingsSubpage by rememberSaveable { mutableStateOf(com.ujwal.focusgram.feature.settings.SettingsSubpage.MAIN) } // Evaluates whether any barrier, lock, breath pause, effort friction, cooldown, or intention picker is active - val isGateActive = shouldShowLock || - ((isDailyLimitExhausted || isSessionExhausted) && destination != AppDestination.ADSTERRA_REWARDED) || + val isGateActive = destination != AppDestination.ADSTERRA_REWARDED && ( + shouldShowLock || + isDailyLimitExhausted || isSessionExhausted || (remainingCooldownSeconds > 0 && !hasPassedCooldownGate) || (settings.showBreathGate && settings.breathGateSeconds > 0 && !hasPassedBreathGate) || (settings.effortFrictionEnabled && settings.wordChallengeCount > 0 && !hasPassedEffortFriction) || !hasPassedSessionPicker + ) // System File Chooser / Camera / Gallery Launchers for Story, Post, DMs & Profile Uploads val pendingFilePickerCallback = remember { AtomicReference<((List) -> Unit)?>(null) } @@ -562,21 +690,32 @@ fun FocusGramApp() { } } + val currentDestination by rememberUpdatedState(destination) + val currentHasPassedSessionPicker by rememberUpdatedState(hasPassedSessionPicker) + val currentTotalElapsedSeconds by rememberUpdatedState(totalElapsedSeconds) + // Lifecycle observer for foreground/background state, media pausing, and auto-lock DisposableEffect(lifecycleOwner, settings.appLockEnabled, settings.autoLockOnBackground) { val observer = LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_STOP) { isAppInForeground = false sessionManager.pauseMedia() - if (hasPassedSessionPicker && totalElapsedSeconds >= 15) { + if (currentHasPassedSessionPicker && currentTotalElapsedSeconds >= 15) { scope.launch { settingsRepository.recordSessionEnd() } } - if (settings.appLockEnabled && (settings.autoLockOnBackground || !hasPassedSessionPicker)) { - isAppUnlocked = false + // Do not lock the app if the user is currently on the rewarded ad screen (e.g. clicking out to view an ad in browser) + if (currentDestination != AppDestination.ADSTERRA_REWARDED) { + if (settings.appLockEnabled && (settings.autoLockOnBackground || !currentHasPassedSessionPicker)) { + isAppUnlocked = false + } + if (settings.autoLockOnBackground) { + unlockedChatThreadIds = emptySet() + isDirectAllUnlocked = false + } } } else if (event == Lifecycle.Event.ON_START) { isAppInForeground = true - if (destination == AppDestination.MAIN_WEBVIEW && !isGateActive) { + if (currentDestination == AppDestination.MAIN_WEBVIEW && !isGateActive) { sessionManager.resumeMedia() } } @@ -595,12 +734,22 @@ fun FocusGramApp() { extensionManager.onInputFocused = { focused -> isWebInputFocused = focused } + extensionManager.onBioInputFocused = { focused -> + isBioFocused = focused + } extensionManager.onUrlChanged = { newUrl -> val mode = IslandMode.fromUrl(newUrl) + val lower = newUrl.lowercase() + val isAuthRoute = (lower.contains("/accounts") && !lower.contains("/accounts/edit")) || lower.contains("/login") || lower.contains("/signup") + isAuthPage = isAuthRoute + if (!isAuthRoute) { + isUserAuthenticated = true + } sessionManager.updateCurrentUrl(newUrl) sessionManager.updateIslandMode(mode) extensionManager.setIslandMode(mode) isWebInputFocused = false + isBioFocused = false isModalActive = mode == IslandMode.HIDDEN } extensionManager.onModalOrChatActive = { active -> @@ -680,13 +829,16 @@ fun FocusGramApp() { onRouteChanged = { newUrl -> val mode = IslandMode.fromUrl(newUrl) val lower = newUrl.lowercase() - if (lower.contains("/accounts") || lower.contains("/login") || lower.contains("/signup")) { - isAuthPage = true + val isAuthRoute = (lower.contains("/accounts") && !lower.contains("/accounts/edit")) || lower.contains("/login") || lower.contains("/signup") + isAuthPage = isAuthRoute + if (!isAuthRoute) { + isUserAuthenticated = true } sessionManager.updateCurrentUrl(newUrl) sessionManager.updateIslandMode(mode) extensionManager.setIslandMode(mode) isWebInputFocused = false + isBioFocused = false isModalActive = mode == IslandMode.HIDDEN } ) @@ -873,6 +1025,82 @@ fun FocusGramApp() { modifier = Modifier.align(Alignment.TopCenter) ) + // Native DM Chat Header Lock Overlay Button (positioned adjacent to Instagram's Info button) + if (!isGateActive && destination == AppDestination.MAIN_WEBVIEW && currentThreadId != null && settings.chatLockMode == "individual") { + val isChatExplicitlyLocked = remember(currentThreadId, settings.lockedChatIds, threadToUsernameMap.size, settings.lockedChatUsernames.size) { + val associatedUsers = threadToUsernameMap[currentThreadId] ?: emptySet() + val mappedName = settings.lockedChatUsernames[currentThreadId] + settings.lockedChatIds.any { lockedId -> + val clean = lockedId.trim().lowercase().removePrefix("@") + clean.equals(currentThreadId, ignoreCase = true) || + associatedUsers.any { it.equals(clean, ignoreCase = true) } || + (!mappedName.isNullOrBlank() && clean.equals(mappedName.lowercase().trim().removePrefix("@"), ignoreCase = true)) + } + } + val isCurrentlyLocked = isChatExplicitlyLocked + + Box( + modifier = Modifier + .align(Alignment.TopEnd) + .statusBarsPadding() + .padding(end = 52.dp, top = 2.dp) + .size(44.dp), + contentAlignment = Alignment.Center + ) { + val iconTint = if (isCurrentlyLocked) { + Color(0xFFFF3B30) + } else if (isAppLight) { + Color(0xFF262626) + } else { + Color.White.copy(alpha = 0.9f) + } + + IconButton( + onClick = { + var username = threadToUsernameMap[currentThreadId]?.firstOrNull() + ?: settings.lockedChatUsernames[currentThreadId] + scope.launch { + if (username.isNullOrBlank()) { + try { + sessionManager.userScriptManager?.evaluate( + sessionManager.session, + "if (typeof window.__fgGetThreadParticipant === 'function') { window.__fgGetThreadParticipant(); }" + ) + } catch (_: Exception) {} + username = threadToUsernameMap[currentThreadId]?.firstOrNull() + ?: settings.lockedChatUsernames[currentThreadId] + } + val isNowLocked = settingsRepository.toggleLockedChat(currentThreadId, username) + if (isNowLocked) { + // Conversation is now locked: engage lock immediately + unlockedChatThreadIds = unlockedChatThreadIds - currentThreadId + extensionManager.notifyChatLocked(currentThreadId) + } else { + // Conversation is now unlocked: keep unlocked in current session + unlockedChatThreadIds = unlockedChatThreadIds + currentThreadId + extensionManager.notifyChatUnlocked(currentThreadId, isAll = false) + } + val label = if (!username.isNullOrBlank()) "@$username" else "Conversation" + val msg = if (isNowLocked) "Locked $label" else "Unlocked $label" + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show() + HapticHelper.performClick(context) + } + }, + modifier = Modifier.size(40.dp) + ) { + Icon( + painter = androidx.compose.ui.res.painterResource( + if (isCurrentlyLocked) com.ujwal.focusgram.R.drawable.ic_chat_lock_closed + else com.ujwal.focusgram.R.drawable.ic_chat_lock_open + ), + contentDescription = if (isCurrentlyLocked) "Unlock conversation" else "Lock conversation", + tint = iconTint, + modifier = Modifier.size(22.dp) + ) + } + } + } + // Ambient background behind the floating nav bar on Reels (seamless gradient, no harsh border line) if (!isGateActive && destination == AppDestination.MAIN_WEBVIEW && islandMode == IslandMode.FLOATING && !isKeyboardOrInputActive) { Box( @@ -941,6 +1169,64 @@ fun FocusGramApp() { ) } + // Native Floating Bio Font Stylist (Anchored directly above the Soft Keyboard via imePadding) + if (isBioFocused && !isGateActive && destination == AppDestination.MAIN_WEBVIEW) { + Surface( + modifier = Modifier + .align(Alignment.BottomCenter) + .imePadding() + .padding(horizontal = 16.dp, vertical = 8.dp), + shape = RoundedCornerShape(20.dp), + color = Color(0xFA181820), + border = BorderStroke(1.dp, Color(0x33FFFFFF)), + shadowElevation = 8.dp + ) { + Row( + modifier = Modifier + .horizontalScroll(rememberScrollState()) + .padding(horizontal = 10.dp, vertical = 6.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + listOf( + "normal" to "Normal", + "bold" to "Bold", + "sans" to "Sans", + "sans_italic" to "Italic", + "mono" to "Mono", + "gothic" to "Gothic", + "script" to "Script" + ).forEach { (id, label) -> + val isSelected = selectedBioStyle == id + Box( + modifier = Modifier + .clip(RoundedCornerShape(14.dp)) + .background(if (isSelected) Color.White else Color(0xFF262626)) + .border( + width = 1.dp, + color = if (isSelected) Color.White else Color(0x33FFFFFF), + shape = RoundedCornerShape(14.dp) + ) + .clickable { + selectedBioStyle = id + extensionManager.setBioStyle(id) + HapticHelper.performClick(context) + sessionManager.session.loadUri("javascript:(function(){window.__fgSetBioStyle&&window.__fgSetBioStyle('$id');})()") + } + .padding(horizontal = 14.dp, vertical = 6.dp) + ) { + Text( + text = label, + color = if (isSelected) Color.Black else Color(0xFFD1D5DB), + fontSize = 13.sp, + fontWeight = if (isSelected) FontWeight.SemiBold else FontWeight.Medium + ) + } + } + } + } + } + // Sub-screen Animated Overlay (Settings, Reels History, App Lock, etc.) AnimatedVisibility( visible = !isGateActive && destination != AppDestination.MAIN_WEBVIEW, @@ -971,6 +1257,7 @@ fun FocusGramApp() { AppDestination.SETTINGS -> { com.ujwal.focusgram.feature.settings.SettingsScreen( repository = settingsRepository, + inputSettings = settings, onBack = { destination = AppDestination.MAIN_WEBVIEW }, onNavigateReelsHistory = { destination = AppDestination.REELS_HISTORY }, onNavigateScreenTime = { destination = AppDestination.SCREEN_TIME }, @@ -987,7 +1274,9 @@ fun FocusGramApp() { screenTimeDao = database.screenTimeDao(), reelHistory = reelHistory, currentSubpage = settingsSubpage, - onSubpageChange = { settingsSubpage = it } + onSubpageChange = { settingsSubpage = it }, + encryptedStorage = encryptedStorage, + onNavigateChatPinSetup = { destination = AppDestination.CHAT_LOCK_SETUP } ) } @@ -1043,7 +1332,20 @@ fun FocusGramApp() { repository = settingsRepository, encryptedStorage = encryptedStorage, onBack = { destination = AppDestination.SETTINGS }, - onChangePin = { destination = AppDestination.APP_LOCK_SETUP } + onChangePin = { destination = AppDestination.APP_LOCK_SETUP }, + onChangeChatPin = { destination = AppDestination.CHAT_LOCK_SETUP } + ) + } + + AppDestination.CHAT_LOCK_SETUP -> { + AppLockSetupScreen( + encryptedStorage = encryptedStorage, + settingsRepository = settingsRepository, + onBack = { destination = AppDestination.APP_LOCK_SETTINGS }, + onSuccess = { destination = AppDestination.APP_LOCK_SETTINGS }, + title = "Set Chat Lock PIN", + subtitle = "Used to unlock protected Direct Messages and conversations.", + isChatPinSetup = true ) } @@ -1061,8 +1363,15 @@ fun FocusGramApp() { val pendingAction = adRewardAction adRewardAction = null if (pendingAction != null) { - scope.launch { pendingAction.invoke() } - destination = AppDestination.SETTINGS + scope.launch { + try { + pendingAction.invoke() + } catch (e: Exception) { + Log.e("FocusGramApp", "Failed to apply rewarded setting action", e) + } finally { + destination = AppDestination.SETTINGS + } + } } else if (isDailyLimitExhausted) { scope.launch { settingsRepository.extendDailyLimit5Minutes(today) } sessionRemainingSeconds += 5 * 60 @@ -1166,6 +1475,117 @@ fun FocusGramApp() { } } } + + // Chat Lock Privacy Screen (Instant Black Cover + Hardware Biometric / PIN Gate) + if (destination == AppDestination.MAIN_WEBVIEW && !isGateActive && isChatLockActive) { + Box( + modifier = Modifier + .fillMaxSize() + .background(PureBlack) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null + ) {} + ) { + val activeThread = pendingUnlockChat?.threadId ?: currentThreadId + val lockedUsername = pendingUnlockChat?.username + ?: activeThread?.let { settings.lockedChatUsernames[it] } + ?: activeThread?.let { threadToUsernameMap[it]?.firstOrNull() } + val chatTitle = when { + settings.chatLockAll && activeThread == null -> "Direct Messages" + !lockedUsername.isNullOrBlank() -> "@$lockedUsername" + else -> "Locked Conversation" + } + ChatLockScreen( + encryptedStorage = encryptedStorage, + isBiometricAllowed = settings.chatBiometricEnabled, + title = chatTitle, + subtitle = "Enter 4-digit PIN to view conversation", + customVerifyPin = if (settings.useSeparateChatPin && encryptedStorage.hasChatPin()) { + { pin -> encryptedStorage.verifyChatPin(pin) } + } else null, + onCancel = { + val pending = pendingUnlockChat + pendingUnlockChat = null + if (currentThreadId != null) { + unlockedChatThreadIds = unlockedChatThreadIds - currentThreadId + } + sessionManager.userScriptManager?.evaluate(sessionManager.session, """ + if (typeof window.__fgRemovePrivacyVeil === 'function') { + window.__fgRemovePrivacyVeil(); + } + """) + if (settings.chatLockMode == "whole_dm" || settings.chatLockAll) { + sessionManager.navigateTo("https://www.instagram.com/") + } else { + sessionManager.navigateTo("https://www.instagram.com/direct/inbox/") + } + }, + onUnlockSuccess = { + val pending = pendingUnlockChat + if (pending != null) { + pendingUnlockChat = null + unlockedChatThreadIds = unlockedChatThreadIds + pending.threadId + extensionManager.notifyChatUnlocked(pending.threadId, isAll = false) + + val cleanId = pending.threadId.lowercase().trim() + sessionManager.userScriptManager?.evaluate(sessionManager.session, """ + window.__fgUnlockedThreads = window.__fgUnlockedThreads || []; + if (!window.__fgUnlockedThreads.includes('$cleanId')) { + window.__fgUnlockedThreads.push('$cleanId'); + } + if (typeof window.__fgRemovePrivacyVeil === 'function') { + window.__fgRemovePrivacyVeil(); + } + window.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { + detail: { unlockedThreads: window.__fgUnlockedThreads } + })); + """) + + val dest = pending.targetUrl ?: "https://www.instagram.com/direct/t/${pending.threadId}/" + val current = sessionManager.currentUrl.value + if (current.contains(pending.threadId)) { + sessionManager.session.reload() + } else { + sessionManager.navigateTo(dest) + } + } else if ((settings.chatLockMode == "whole_dm" || settings.chatLockAll) && currentThreadId == null) { + isDirectAllUnlocked = true + extensionManager.notifyChatUnlocked("", isAll = true) + sessionManager.userScriptManager?.evaluate(sessionManager.session, """ + window.__fgUnlockedThreads = window.__fgUnlockedThreads || []; + if (!window.__fgUnlockedThreads.includes('__all__')) { + window.__fgUnlockedThreads.push('__all__'); + } + if (typeof window.__fgRemovePrivacyVeil === 'function') { + window.__fgRemovePrivacyVeil(); + } + window.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { + detail: { unlockedThreads: window.__fgUnlockedThreads } + })); + """) + } else if (currentThreadId != null) { + val cleanId = currentThreadId.lowercase().trim() + unlockedChatThreadIds = unlockedChatThreadIds + currentThreadId + extensionManager.notifyChatUnlocked(currentThreadId, isAll = false) + sessionManager.userScriptManager?.evaluate(sessionManager.session, """ + window.__fgUnlockedThreads = window.__fgUnlockedThreads || []; + if (!window.__fgUnlockedThreads.includes('$cleanId')) { + window.__fgUnlockedThreads.push('$cleanId'); + } + if (typeof window.__fgRemovePrivacyVeil === 'function') { + window.__fgRemovePrivacyVeil(); + } + window.dispatchEvent(new CustomEvent('focusgram:chat-lock-sync', { + detail: { unlockedThreads: window.__fgUnlockedThreads } + })); + """) + sessionManager.session.reload() + } + } + ) + } + } } } } diff --git a/Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_abstract.png b/Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_abstract.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a59aefbc088eb1c53837d1e9ce377880a92353 GIT binary patch literal 251468 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

qP-_KXy{fwXR>~1 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 P00000NkvXXu0mjf{uh<8 literal 0 HcmV?d00001 diff --git a/Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_forest.png b/Ported/app/src/main/res/drawable-xxxhdpi/ic_launcher_fg_forest.png new file mode 100644 index 0000000000000000000000000000000000000000..c2cca8ef234dac264f6cc24c3a010c2495d995c3 GIT binary patch literal 418577 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

H@CI-gdk;GiGatjt6bB( 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