Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
73d0cef
created site settings menu and list of main permissions
Brooksolomon Sep 8, 2025
530f087
Added additional permissions
Brooksolomon Sep 8, 2025
204114c
navigation into and out of site settings working
Brooksolomon Sep 8, 2025
ee0cd9f
created site settings view
Brooksolomon Sep 8, 2025
6bc2444
replaced with query for realtime updates to permission change
Brooksolomon Sep 8, 2025
3cf6c0f
Added separation of permissions so that setting one doesnt mean trigg…
Brooksolomon Sep 8, 2025
876a5e8
added search bar to filter domains
Brooksolomon Sep 8, 2025
7dea7ce
added dynmaic view window for all permissions
Brooksolomon Sep 8, 2025
7d8553d
created small menu on the three dots
Brooksolomon Sep 8, 2025
94849a6
connected mini menu with the settings and the storage so now everythi…
Brooksolomon Sep 8, 2025
d7c8cb2
added more settings button functionality
Brooksolomon Sep 8, 2025
268e19f
scale pemission managment backend to all permissions
Brooksolomon Sep 9, 2025
d20ed58
added logic to communicate with asking permissions and let the user a…
Brooksolomon Sep 9, 2025
8779987
added camera and mic request to info.plist so that we can ask from th…
Brooksolomon Sep 9, 2025
1c1ad3a
removed javascript injectors and implimented it with UI deligates
Brooksolomon Sep 15, 2025
34a2956
removed all the other permissions and only kept camera and micraphoen
Brooksolomon Sep 16, 2025
4364098
added detection and refresh when the menu changes
Brooksolomon Sep 16, 2025
fcd4cd9
Merge branch 'main' into feature/permissions-settings
kenenisa Sep 16, 2025
e16c589
refactor: clean up Info.plist formatting and update Tab and URLBar im…
kenenisa Sep 16, 2025
7a05293
feat : added permissions to project.yml
Brooksolomon Sep 18, 2025
b0ac9aa
feat : added site permissions to ORa.root
Brooksolomon Sep 18, 2025
07b86c6
Merge branch 'main' into feature/permissions-settings
Brooksolomon Sep 26, 2025
7e3c4d4
feat : removed duplicate webview handlers
Brooksolomon Oct 14, 2025
32e6147
Merge branch 'main' into feature/permissions-settings
kenenisa Oct 14, 2025
66b99f2
fix : Resolved code lost in merge conflict
Brooksolomon Oct 14, 2025
948c471
fix : settings remove button linked with permission store
Brooksolomon Oct 14, 2025
8965db7
fix : Separated extension logic to its own file
Brooksolomon Oct 14, 2025
9d3037d
fix : added blank tab opener to ui deligate handlers
Brooksolomon Oct 14, 2025
abb0347
fix : moved all the UI delegate code to the coordinator
Brooksolomon Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ora/Common/Extensions/ModelConfiguration+Shared.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extension ModelConfiguration {
} else {
return ModelConfiguration(
"OraData",
schema: Schema([TabContainer.self, History.self, Download.self]),
schema: Schema([TabContainer.self, History.self, Download.self, SitePermission.self]),
url: URL.applicationSupportDirectory.appending(path: "Ora/OraData.sqlite")
)
}
Expand All @@ -18,7 +18,7 @@ extension ModelConfiguration {
/// Creates a ModelContainer using the standard Ora database configuration
static func createOraContainer(isPrivate: Bool = false) throws -> ModelContainer {
return try ModelContainer(
for: TabContainer.self, History.self, Download.self,
for: TabContainer.self, History.self, Download.self, SitePermission.self,
configurations: oraDatabase(isPrivate: isPrivate)
)
}
Expand Down
4 changes: 4 additions & 0 deletions ora/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSCameraUsageDescription</key>
<string>Ora requires access to your camera to support video features.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Ora requires access to your microphone to support audio features.</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.web-browser</string>
<key>LSMinimumSystemVersion</key>
Expand Down
27 changes: 27 additions & 0 deletions ora/Models/SitePermission.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation
import SwiftData

@Model
final class SitePermission {
@Attribute(.unique) var host: String

// Permissions
var cameraAllowed: Bool
var microphoneAllowed: Bool

// Track which permissions have been explicitly set
var cameraConfigured: Bool
var microphoneConfigured: Bool

init(
host: String,
cameraAllowed: Bool = false,
microphoneAllowed: Bool = false
) {
self.host = host
self.cameraAllowed = cameraAllowed
self.microphoneAllowed = microphoneAllowed
self.cameraConfigured = false
self.microphoneConfigured = false
}
}
12 changes: 1 addition & 11 deletions ora/Models/Tab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class Tab: ObservableObject, Identifiable {
layer.drawsAsynchronously = true
}

// Set up navigation delegate
// Set up navigation delegate and UI delegate

// Don't automatically load URL - let TabManager handle it
// This prevents all tabs from loading on app launch
Expand Down Expand Up @@ -358,16 +358,6 @@ class Tab: ObservableObject, Identifiable {
// Navigation failed
}

func webView(
_ webView: WKWebView,
requestMediaCapturePermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo,
decisionHandler: @escaping (WKPermissionDecision) -> Void
) {
// For now, grant all
decisionHandler(.grant)
}

func destroyWebView() {
webView.stopLoading()
webView.navigationDelegate = nil
Expand Down
3 changes: 2 additions & 1 deletion ora/Modules/Browser/BrowserView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ struct BrowserView: View {
isDownloadsPopoverOpen: downloadManager.isDownloadsPopoverOpen
)
}

// Permission dialog overlay
PermissionDialogOverlay()
if toolbarManager.isToolbarHidden {
FloatingURLBar(
showFloatingURLBar: $showFloatingURLBar,
Expand Down
58 changes: 41 additions & 17 deletions ora/Modules/Settings/Sections/PrivacySecuritySettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,51 @@ struct PrivacySecuritySettingsView: View {
@StateObject private var settings = SettingsStore.shared

var body: some View {
SettingsContainer(maxContentWidth: 760) {
Form {
VStack(alignment: .leading, spacing: 32) {
VStack(alignment: .leading, spacing: 8) {
Section {
Text("Tracking Prevention").foregroundStyle(.secondary)
Toggle("Block third-party trackers", isOn: $settings.blockThirdPartyTrackers)
Toggle("Block fingerprinting", isOn: $settings.blockFingerprinting)
Toggle("Ad Blocking", isOn: $settings.adBlocking)
NavigationStack {
SettingsContainer(maxContentWidth: 760) {
Form {
VStack(alignment: .leading, spacing: 32) {
VStack(alignment: .leading, spacing: 8) {
Section {
Text("Tracking Prevention").foregroundStyle(.secondary)
Toggle("Block third-party trackers", isOn: $settings.blockThirdPartyTrackers)
Toggle("Block fingerprinting", isOn: $settings.blockFingerprinting)
Toggle("Ad Blocking", isOn: $settings.adBlocking)
}
}

VStack(alignment: .leading, spacing: 8) {
Section {
Text("Cookies").foregroundStyle(.secondary)
Picker("", selection: $settings.cookiesPolicy) {
ForEach(CookiesPolicy.allCases) { policy in
Text(policy.rawValue).tag(policy)
}
}
.pickerStyle(.radioGroup)
}
}
}

VStack(alignment: .leading, spacing: 8) {
Section {
Text("Cookies").foregroundStyle(.secondary)
Picker("", selection: $settings.cookiesPolicy) {
ForEach(CookiesPolicy.allCases) { policy in
Text(policy.rawValue).tag(policy)
VStack(alignment: .leading, spacing: 12) {
Section {
NavigationLink {
SiteSettingsView()
.navigationBarBackButtonHidden(true)
} label: {
HStack(spacing: 12) {
Image(systemName: "gear")
VStack(alignment: .leading, spacing: 2) {
Text("Site settings")
Text("Manage permissions by site")
.font(.subheadline)
.foregroundStyle(.secondary)
}
Spacer()
Image(systemName: "chevron.right")
.foregroundStyle(.tertiary)
}
}
}
.pickerStyle(.radioGroup)
}
}
}
Expand Down
Loading
Loading