Add new settings.
This commit is contained in:
parent
c5e177463e
commit
de260b8758
|
@ -133,6 +133,8 @@
|
||||||
F8AD061329A565620042F111 /* String+Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8AD061229A565620042F111 /* String+Random.swift */; };
|
F8AD061329A565620042F111 /* String+Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8AD061229A565620042F111 /* String+Random.swift */; };
|
||||||
F8AFF7C129B259150087D083 /* TrendingTagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8AFF7C029B259150087D083 /* TrendingTagsView.swift */; };
|
F8AFF7C129B259150087D083 /* TrendingTagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8AFF7C029B259150087D083 /* TrendingTagsView.swift */; };
|
||||||
F8AFF7C429B25EF40087D083 /* TagImagesGridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8AFF7C329B25EF40087D083 /* TagImagesGridView.swift */; };
|
F8AFF7C429B25EF40087D083 /* TagImagesGridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8AFF7C329B25EF40087D083 /* TagImagesGridView.swift */; };
|
||||||
|
F8B05ACB29B489B100857221 /* HapticsSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B05ACA29B489B100857221 /* HapticsSectionView.swift */; };
|
||||||
|
F8B05ACE29B48E2F00857221 /* MediaSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B05ACD29B48E2F00857221 /* MediaSettingsView.swift */; };
|
||||||
F8B0885E29942E31002AB40A /* ThirdPartyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B0885D29942E31002AB40A /* ThirdPartyView.swift */; };
|
F8B0885E29942E31002AB40A /* ThirdPartyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B0885D29942E31002AB40A /* ThirdPartyView.swift */; };
|
||||||
F8B0886029943498002AB40A /* OtherSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B0885F29943498002AB40A /* OtherSectionView.swift */; };
|
F8B0886029943498002AB40A /* OtherSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B0885F29943498002AB40A /* OtherSectionView.swift */; };
|
||||||
F8B08862299435C9002AB40A /* SupportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B08861299435C9002AB40A /* SupportView.swift */; };
|
F8B08862299435C9002AB40A /* SupportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B08861299435C9002AB40A /* SupportView.swift */; };
|
||||||
|
@ -287,6 +289,10 @@
|
||||||
F8AD061229A565620042F111 /* String+Random.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Random.swift"; sourceTree = "<group>"; };
|
F8AD061229A565620042F111 /* String+Random.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Random.swift"; sourceTree = "<group>"; };
|
||||||
F8AFF7C029B259150087D083 /* TrendingTagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingTagsView.swift; sourceTree = "<group>"; };
|
F8AFF7C029B259150087D083 /* TrendingTagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingTagsView.swift; sourceTree = "<group>"; };
|
||||||
F8AFF7C329B25EF40087D083 /* TagImagesGridView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagImagesGridView.swift; sourceTree = "<group>"; };
|
F8AFF7C329B25EF40087D083 /* TagImagesGridView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagImagesGridView.swift; sourceTree = "<group>"; };
|
||||||
|
F8B05AC929B488C600857221 /* Vernissage-003.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-003.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
F8B05ACA29B489B100857221 /* HapticsSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticsSectionView.swift; sourceTree = "<group>"; };
|
||||||
|
F8B05ACC29B48DD000857221 /* Vernissage-004.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage-004.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
|
F8B05ACD29B48E2F00857221 /* MediaSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSettingsView.swift; sourceTree = "<group>"; };
|
||||||
F8B0885D29942E31002AB40A /* ThirdPartyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartyView.swift; sourceTree = "<group>"; };
|
F8B0885D29942E31002AB40A /* ThirdPartyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartyView.swift; sourceTree = "<group>"; };
|
||||||
F8B0885F29943498002AB40A /* OtherSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OtherSectionView.swift; sourceTree = "<group>"; };
|
F8B0885F29943498002AB40A /* OtherSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OtherSectionView.swift; sourceTree = "<group>"; };
|
||||||
F8B08861299435C9002AB40A /* SupportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportView.swift; sourceTree = "<group>"; };
|
F8B08861299435C9002AB40A /* SupportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -509,6 +515,8 @@
|
||||||
F8B0885F29943498002AB40A /* OtherSectionView.swift */,
|
F8B0885F29943498002AB40A /* OtherSectionView.swift */,
|
||||||
F8B08861299435C9002AB40A /* SupportView.swift */,
|
F8B08861299435C9002AB40A /* SupportView.swift */,
|
||||||
F86A4306299AA5E900DF7645 /* ThanksView.swift */,
|
F86A4306299AA5E900DF7645 /* ThanksView.swift */,
|
||||||
|
F8B05ACA29B489B100857221 /* HapticsSectionView.swift */,
|
||||||
|
F8B05ACD29B48E2F00857221 /* MediaSettingsView.swift */,
|
||||||
);
|
);
|
||||||
path = Subviews;
|
path = Subviews;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -864,6 +872,7 @@
|
||||||
F897978A2968314A00B22335 /* LoadingIndicator.swift in Sources */,
|
F897978A2968314A00B22335 /* LoadingIndicator.swift in Sources */,
|
||||||
F8B9B351298D4B34009CC69C /* Client+Account.swift in Sources */,
|
F8B9B351298D4B34009CC69C /* Client+Account.swift in Sources */,
|
||||||
F8210DE52966E160001D9973 /* Color+SystemColors.swift in Sources */,
|
F8210DE52966E160001D9973 /* Color+SystemColors.swift in Sources */,
|
||||||
|
F8B05ACB29B489B100857221 /* HapticsSectionView.swift in Sources */,
|
||||||
F88FAD2B295F43B8009B20C9 /* AccountData+CoreDataProperties.swift in Sources */,
|
F88FAD2B295F43B8009B20C9 /* AccountData+CoreDataProperties.swift in Sources */,
|
||||||
F85D4975296407F100751DF7 /* HomeTimelineService.swift in Sources */,
|
F85D4975296407F100751DF7 /* HomeTimelineService.swift in Sources */,
|
||||||
F80048062961850500E6868A /* StatusData+CoreDataProperties.swift in Sources */,
|
F80048062961850500E6868A /* StatusData+CoreDataProperties.swift in Sources */,
|
||||||
|
@ -887,6 +896,7 @@
|
||||||
F8B9B353298D4B5D009CC69C /* Client+Search.swift in Sources */,
|
F8B9B353298D4B5D009CC69C /* Client+Search.swift in Sources */,
|
||||||
F85D497B29640C8200751DF7 /* UsernameRow.swift in Sources */,
|
F85D497B29640C8200751DF7 /* UsernameRow.swift in Sources */,
|
||||||
F86A4305299AA12800DF7645 /* PurchaseError.swift in Sources */,
|
F86A4305299AA12800DF7645 /* PurchaseError.swift in Sources */,
|
||||||
|
F8B05ACE29B48E2F00857221 /* MediaSettingsView.swift in Sources */,
|
||||||
F89D6C4429718092001DA3D4 /* AccentsSectionView.swift in Sources */,
|
F89D6C4429718092001DA3D4 /* AccentsSectionView.swift in Sources */,
|
||||||
F88E4D42297E69FD0057491A /* StatusesView.swift in Sources */,
|
F88E4D42297E69FD0057491A /* StatusesView.swift in Sources */,
|
||||||
F86FB555298BF83F000131F0 /* FavouriteTouch.swift in Sources */,
|
F86FB555298BF83F000131F0 /* FavouriteTouch.swift in Sources */,
|
||||||
|
@ -1115,7 +1125,7 @@
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 48;
|
CURRENT_PROJECT_VERSION = 49;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
|
@ -1152,7 +1162,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 48;
|
CURRENT_PROJECT_VERSION = 49;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Vernissage/Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
DEVELOPMENT_TEAM = B2U9FEKYP8;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
|
@ -1281,11 +1291,13 @@
|
||||||
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */ = {
|
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */ = {
|
||||||
isa = XCVersionGroup;
|
isa = XCVersionGroup;
|
||||||
children = (
|
children = (
|
||||||
|
F8B05ACC29B48DD000857221 /* Vernissage-004.xcdatamodel */,
|
||||||
|
F8B05AC929B488C600857221 /* Vernissage-003.xcdatamodel */,
|
||||||
F89F0605299139F6003DC875 /* Vernissage-002.xcdatamodel */,
|
F89F0605299139F6003DC875 /* Vernissage-002.xcdatamodel */,
|
||||||
F8C937A929882CA90004D782 /* Vernissage-001.xcdatamodel */,
|
F8C937A929882CA90004D782 /* Vernissage-001.xcdatamodel */,
|
||||||
F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */,
|
F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */,
|
||||||
);
|
);
|
||||||
currentVersion = F89F0605299139F6003DC875 /* Vernissage-002.xcdatamodel */;
|
currentVersion = F8B05ACC29B48DD000857221 /* Vernissage-004.xcdatamodel */;
|
||||||
path = Vernissage.xcdatamodeld;
|
path = Vernissage.xcdatamodeld;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
versionGroupType = wrapper.xcdatamodel;
|
||||||
|
|
|
@ -18,6 +18,14 @@ extension ApplicationSettings {
|
||||||
@NSManaged public var tintColor: Int32
|
@NSManaged public var tintColor: Int32
|
||||||
@NSManaged public var avatarShape: Int32
|
@NSManaged public var avatarShape: Int32
|
||||||
@NSManaged public var lastRefreshTokens: Date
|
@NSManaged public var lastRefreshTokens: Date
|
||||||
|
|
||||||
|
@NSManaged public var hapticTabSelectionEnabled: Bool
|
||||||
|
@NSManaged public var hapticRefreshEnabled: Bool
|
||||||
|
@NSManaged public var hapticButtonPressEnabled: Bool
|
||||||
|
@NSManaged public var hapticAnimationEnabled: Bool
|
||||||
|
@NSManaged public var hapticNotificationEnabled: Bool
|
||||||
|
|
||||||
|
@NSManaged public var showSensitive: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ApplicationSettings : Identifiable {
|
extension ApplicationSettings : Identifiable {
|
||||||
|
|
|
@ -62,4 +62,40 @@ class ApplicationSettingsHandler {
|
||||||
let context = CoreDataHandler.shared.container.viewContext
|
let context = CoreDataHandler.shared.container.viewContext
|
||||||
return ApplicationSettings(context: context)
|
return ApplicationSettings(context: context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setHapticTabSelectionEnabled(value: Bool) {
|
||||||
|
let defaultSettings = self.getDefaultSettings()
|
||||||
|
defaultSettings.hapticTabSelectionEnabled = value
|
||||||
|
CoreDataHandler.shared.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setHapticRefreshEnabled(value: Bool) {
|
||||||
|
let defaultSettings = self.getDefaultSettings()
|
||||||
|
defaultSettings.hapticRefreshEnabled = value
|
||||||
|
CoreDataHandler.shared.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setHapticAnimationEnabled(value: Bool) {
|
||||||
|
let defaultSettings = self.getDefaultSettings()
|
||||||
|
defaultSettings.hapticAnimationEnabled = value
|
||||||
|
CoreDataHandler.shared.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setHapticNotificationEnabled(value: Bool) {
|
||||||
|
let defaultSettings = self.getDefaultSettings()
|
||||||
|
defaultSettings.hapticNotificationEnabled = value
|
||||||
|
CoreDataHandler.shared.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setHapticButtonPressEnabled(value: Bool) {
|
||||||
|
let defaultSettings = self.getDefaultSettings()
|
||||||
|
defaultSettings.hapticButtonPressEnabled = value
|
||||||
|
CoreDataHandler.shared.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setShowSensitive(value: Bool) {
|
||||||
|
let defaultSettings = self.getDefaultSettings()
|
||||||
|
defaultSettings.showSensitive = value
|
||||||
|
CoreDataHandler.shared.save()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,24 @@ public class ApplicationState: ObservableObject {
|
||||||
/// Status id for showed interaction row.
|
/// Status id for showed interaction row.
|
||||||
@Published var showInteractionStatusId = String.empty()
|
@Published var showInteractionStatusId = String.empty()
|
||||||
|
|
||||||
|
/// Should we fire haptic when user change tabs.
|
||||||
|
@Published var hapticTabSelectionEnabled = true
|
||||||
|
|
||||||
|
/// Should we fire haptic when user refresh list.
|
||||||
|
@Published var hapticRefreshEnabled = true
|
||||||
|
|
||||||
|
/// Should we fire haptic when user tap button.
|
||||||
|
@Published var hapticButtonPressEnabled = true
|
||||||
|
|
||||||
|
/// Should we fire haptic when animation is finished.
|
||||||
|
@Published var hapticAnimationEnabled = true
|
||||||
|
|
||||||
|
/// Should we fire haptic when notification occures.
|
||||||
|
@Published var hapticNotificationEnabled = true
|
||||||
|
|
||||||
|
/// Should sensitive photos without mask.
|
||||||
|
@Published var showSensitive = false
|
||||||
|
|
||||||
public func changeApplicationState(accountModel: AccountModel, instance: Instance?, lastSeenStatusId: String?) {
|
public func changeApplicationState(accountModel: AccountModel, instance: Instance?, lastSeenStatusId: String?) {
|
||||||
self.account = accountModel
|
self.account = accountModel
|
||||||
self.lastSeenStatusId = lastSeenStatusId
|
self.lastSeenStatusId = lastSeenStatusId
|
||||||
|
|
|
@ -15,7 +15,6 @@ public class HapticService {
|
||||||
case dataRefresh(intensity: CGFloat)
|
case dataRefresh(intensity: CGFloat)
|
||||||
case notification(_ type: UINotificationFeedbackGenerator.FeedbackType)
|
case notification(_ type: UINotificationFeedbackGenerator.FeedbackType)
|
||||||
case tabSelection
|
case tabSelection
|
||||||
case timeline
|
|
||||||
case animation
|
case animation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,17 +33,25 @@ public class HapticService {
|
||||||
|
|
||||||
switch type {
|
switch type {
|
||||||
case .buttonPress:
|
case .buttonPress:
|
||||||
impactGenerator.impactOccurred()
|
if ApplicationState.shared.hapticButtonPressEnabled {
|
||||||
|
impactGenerator.impactOccurred()
|
||||||
|
}
|
||||||
case let .dataRefresh(intensity):
|
case let .dataRefresh(intensity):
|
||||||
impactGenerator.impactOccurred(intensity: intensity)
|
if ApplicationState.shared.hapticRefreshEnabled {
|
||||||
|
impactGenerator.impactOccurred(intensity: intensity)
|
||||||
|
}
|
||||||
case let .notification(type):
|
case let .notification(type):
|
||||||
notificationGenerator.notificationOccurred(type)
|
if ApplicationState.shared.hapticNotificationEnabled {
|
||||||
|
notificationGenerator.notificationOccurred(type)
|
||||||
|
}
|
||||||
case .tabSelection:
|
case .tabSelection:
|
||||||
selectionGenerator.selectionChanged()
|
if ApplicationState.shared.hapticTabSelectionEnabled {
|
||||||
case .timeline:
|
selectionGenerator.selectionChanged()
|
||||||
selectionGenerator.selectionChanged()
|
}
|
||||||
case .animation:
|
case .animation:
|
||||||
selectionGenerator.selectionChanged()
|
if ApplicationState.shared.hapticAnimationEnabled {
|
||||||
|
selectionGenerator.selectionChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>_XCCurrentVersionName</key>
|
<key>_XCCurrentVersionName</key>
|
||||||
<string>Vernissage-002.xcdatamodel</string>
|
<string>Vernissage-004.xcdatamodel</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22C65" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||||
|
<entity name="AccountData" representedClassName="AccountData" syncable="YES">
|
||||||
|
<attribute name="accessToken" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="acct" attributeType="String"/>
|
||||||
|
<attribute name="avatar" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="avatarData" optional="YES" attributeType="Binary"/>
|
||||||
|
<attribute name="clientId" attributeType="String"/>
|
||||||
|
<attribute name="clientSecret" attributeType="String"/>
|
||||||
|
<attribute name="clientVapidKey" attributeType="String"/>
|
||||||
|
<attribute name="createdAt" attributeType="String"/>
|
||||||
|
<attribute name="displayName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="followersCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="followingCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="header" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="id" attributeType="String"/>
|
||||||
|
<attribute name="lastSeenStatusId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="locked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="note" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="refreshToken" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="serverUrl" attributeType="URI"/>
|
||||||
|
<attribute name="statusesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="url" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="username" attributeType="String"/>
|
||||||
|
<relationship name="statuses" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="StatusData" inverseName="pixelfedAccount" inverseEntity="StatusData"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="ApplicationSettings" representedClassName="ApplicationSettings" syncable="YES">
|
||||||
|
<attribute name="avatarShape" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="currentAccount" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="hapticAnimationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticButtonPressEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticNotificationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticRefreshEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticTabSelectionEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="lastRefreshTokens" attributeType="Date" defaultDateTimeInterval="694256400" usesScalarValueType="NO"/>
|
||||||
|
<attribute name="theme" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="tintColor" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="YES"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="AttachmentData" representedClassName="AttachmentData" syncable="YES">
|
||||||
|
<attribute name="blurhash" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="data" optional="YES" attributeType="Binary" allowsExternalBinaryDataStorage="YES"/>
|
||||||
|
<attribute name="exifCamera" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="exifCreatedDate" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="exifExposure" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="exifLens" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="id" attributeType="String"/>
|
||||||
|
<attribute name="metaImageHeight" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="metaImageWidth" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="previewUrl" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="remoteUrl" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="statusId" attributeType="String"/>
|
||||||
|
<attribute name="text" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="type" attributeType="String"/>
|
||||||
|
<attribute name="url" attributeType="URI"/>
|
||||||
|
<relationship name="statusRelation" maxCount="1" deletionRule="Nullify" destinationEntity="StatusData" inverseName="attachmentsRelation" inverseEntity="StatusData"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="StatusData" representedClassName="StatusData" syncable="YES">
|
||||||
|
<attribute name="accountAvatar" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="accountDisplayName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="accountId" attributeType="String"/>
|
||||||
|
<attribute name="accountUsername" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="applicationName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="applicationWebsite" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="bookmarked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="content" attributeType="String"/>
|
||||||
|
<attribute name="createdAt" attributeType="String"/>
|
||||||
|
<attribute name="favourited" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="favouritesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="id" attributeType="String"/>
|
||||||
|
<attribute name="inReplyToAccount" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="inReplyToId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="muted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="pinned" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="reblogged" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="rebloggedAccountAvatar" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="rebloggedAccountDisplayName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="rebloggedAccountId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="rebloggedAccountUsername" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="rebloggedStatusId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="reblogsCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="repliesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="sensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="spoilerText" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="uri" attributeType="String"/>
|
||||||
|
<attribute name="url" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="visibility" attributeType="String"/>
|
||||||
|
<relationship name="attachmentsRelation" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="AttachmentData" inverseName="statusRelation" inverseEntity="AttachmentData"/>
|
||||||
|
<relationship name="pixelfedAccount" maxCount="1" deletionRule="Nullify" destinationEntity="AccountData" inverseName="statuses" inverseEntity="AccountData"/>
|
||||||
|
</entity>
|
||||||
|
</model>
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22C65" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||||
|
<entity name="AccountData" representedClassName="AccountData" syncable="YES">
|
||||||
|
<attribute name="accessToken" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="acct" attributeType="String"/>
|
||||||
|
<attribute name="avatar" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="avatarData" optional="YES" attributeType="Binary"/>
|
||||||
|
<attribute name="clientId" attributeType="String"/>
|
||||||
|
<attribute name="clientSecret" attributeType="String"/>
|
||||||
|
<attribute name="clientVapidKey" attributeType="String"/>
|
||||||
|
<attribute name="createdAt" attributeType="String"/>
|
||||||
|
<attribute name="displayName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="followersCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="followingCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="header" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="id" attributeType="String"/>
|
||||||
|
<attribute name="lastSeenStatusId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="locked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="note" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="refreshToken" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="serverUrl" attributeType="URI"/>
|
||||||
|
<attribute name="statusesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="url" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="username" attributeType="String"/>
|
||||||
|
<relationship name="statuses" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="StatusData" inverseName="pixelfedAccount" inverseEntity="StatusData"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="ApplicationSettings" representedClassName="ApplicationSettings" syncable="YES">
|
||||||
|
<attribute name="avatarShape" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="currentAccount" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="hapticAnimationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticButtonPressEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticNotificationEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticRefreshEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="hapticTabSelectionEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="lastRefreshTokens" attributeType="Date" defaultDateTimeInterval="694256400" usesScalarValueType="NO"/>
|
||||||
|
<attribute name="showSensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="theme" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="tintColor" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="YES"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="AttachmentData" representedClassName="AttachmentData" syncable="YES">
|
||||||
|
<attribute name="blurhash" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="data" optional="YES" attributeType="Binary" allowsExternalBinaryDataStorage="YES"/>
|
||||||
|
<attribute name="exifCamera" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="exifCreatedDate" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="exifExposure" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="exifLens" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="id" attributeType="String"/>
|
||||||
|
<attribute name="metaImageHeight" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="metaImageWidth" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="previewUrl" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="remoteUrl" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="statusId" attributeType="String"/>
|
||||||
|
<attribute name="text" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="type" attributeType="String"/>
|
||||||
|
<attribute name="url" attributeType="URI"/>
|
||||||
|
<relationship name="statusRelation" maxCount="1" deletionRule="Nullify" destinationEntity="StatusData" inverseName="attachmentsRelation" inverseEntity="StatusData"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="StatusData" representedClassName="StatusData" syncable="YES">
|
||||||
|
<attribute name="accountAvatar" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="accountDisplayName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="accountId" attributeType="String"/>
|
||||||
|
<attribute name="accountUsername" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="applicationName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="applicationWebsite" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="bookmarked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="content" attributeType="String"/>
|
||||||
|
<attribute name="createdAt" attributeType="String"/>
|
||||||
|
<attribute name="favourited" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="favouritesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="id" attributeType="String"/>
|
||||||
|
<attribute name="inReplyToAccount" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="inReplyToId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="muted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="pinned" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="reblogged" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="rebloggedAccountAvatar" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="rebloggedAccountDisplayName" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="rebloggedAccountId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="rebloggedAccountUsername" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="rebloggedStatusId" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="reblogsCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="repliesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="sensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||||
|
<attribute name="spoilerText" optional="YES" attributeType="String"/>
|
||||||
|
<attribute name="uri" attributeType="String"/>
|
||||||
|
<attribute name="url" optional="YES" attributeType="URI"/>
|
||||||
|
<attribute name="visibility" attributeType="String"/>
|
||||||
|
<relationship name="attachmentsRelation" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="AttachmentData" inverseName="statusRelation" inverseEntity="AttachmentData"/>
|
||||||
|
<relationship name="pixelfedAccount" maxCount="1" deletionRule="Nullify" destinationEntity="AccountData" inverseName="statuses" inverseEntity="AccountData"/>
|
||||||
|
</entity>
|
||||||
|
</model>
|
|
@ -34,6 +34,12 @@ struct SettingsView: View {
|
||||||
// Avatar shapes.
|
// Avatar shapes.
|
||||||
AvatarShapesSectionView()
|
AvatarShapesSectionView()
|
||||||
|
|
||||||
|
// Media settings view.
|
||||||
|
MediaSettingsView()
|
||||||
|
|
||||||
|
// Haptics.
|
||||||
|
HapticsSectionView()
|
||||||
|
|
||||||
// Support.
|
// Support.
|
||||||
SupportView()
|
SupportView()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct HapticsSectionView: View {
|
||||||
|
@EnvironmentObject var applicationState: ApplicationState
|
||||||
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
|
@State var hapticTabSelectionEnabled = true
|
||||||
|
@State var hapticButtonPressEnabled = true
|
||||||
|
@State var hapticRefreshEnabled = true
|
||||||
|
@State var hapticAnimationEnabled = true
|
||||||
|
@State var hapticNotificationEnabled = true
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Section("Haptics") {
|
||||||
|
|
||||||
|
Toggle("Tab selection", isOn: $hapticTabSelectionEnabled)
|
||||||
|
.onChange(of: hapticTabSelectionEnabled) { newValue in
|
||||||
|
self.applicationState.hapticTabSelectionEnabled = newValue
|
||||||
|
ApplicationSettingsHandler.shared.setHapticTabSelectionEnabled(value: newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
Toggle("Button press", isOn: $hapticButtonPressEnabled)
|
||||||
|
.onChange(of: hapticButtonPressEnabled) { newValue in
|
||||||
|
self.applicationState.hapticButtonPressEnabled = newValue
|
||||||
|
ApplicationSettingsHandler.shared.setHapticButtonPressEnabled(value: newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
Toggle("List refresh", isOn: $hapticRefreshEnabled)
|
||||||
|
.onChange(of: hapticRefreshEnabled) { newValue in
|
||||||
|
self.applicationState.hapticRefreshEnabled = newValue
|
||||||
|
ApplicationSettingsHandler.shared.setHapticRefreshEnabled(value: newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
Toggle("Animation finished", isOn: $hapticAnimationEnabled)
|
||||||
|
.onChange(of: hapticAnimationEnabled) { newValue in
|
||||||
|
self.applicationState.hapticAnimationEnabled = newValue
|
||||||
|
ApplicationSettingsHandler.shared.setHapticAnimationEnabled(value: newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle("Notification", isOn: $hapticNotificationEnabled)
|
||||||
|
// .onChange(of: hapticNotificationEnabled) { newValue in
|
||||||
|
// self.applicationState.hapticNotificationEnabled = newValue
|
||||||
|
// ApplicationSettingsHandler.shared.setHapticNotificationEnabled(value: newValue)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
let defaultSettings = ApplicationSettingsHandler.shared.getDefaultSettings()
|
||||||
|
self.hapticTabSelectionEnabled = defaultSettings.hapticTabSelectionEnabled
|
||||||
|
self.hapticButtonPressEnabled = defaultSettings.hapticButtonPressEnabled
|
||||||
|
self.hapticRefreshEnabled = defaultSettings.hapticRefreshEnabled
|
||||||
|
self.hapticAnimationEnabled = defaultSettings.hapticAnimationEnabled
|
||||||
|
self.hapticNotificationEnabled = defaultSettings.hapticNotificationEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
//
|
||||||
|
// https://mczachurski.dev
|
||||||
|
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct MediaSettingsView: View {
|
||||||
|
@EnvironmentObject var applicationState: ApplicationState
|
||||||
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
|
@State var showSensitive = true
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Section("Media settings") {
|
||||||
|
|
||||||
|
Toggle("Always show NSFW (sensitive)", isOn: $showSensitive)
|
||||||
|
.onChange(of: showSensitive) { newValue in
|
||||||
|
self.applicationState.showSensitive = newValue
|
||||||
|
ApplicationSettingsHandler.shared.setShowSensitive(value: newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
let defaultSettings = ApplicationSettingsHandler.shared.getDefaultSettings()
|
||||||
|
self.showSensitive = defaultSettings.showSensitive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,7 +46,7 @@ struct ImageRow: View {
|
||||||
if let attachmentData {
|
if let attachmentData {
|
||||||
if let uiImage {
|
if let uiImage {
|
||||||
ZStack {
|
ZStack {
|
||||||
if self.status.sensitive {
|
if self.status.sensitive && !self.applicationState.showSensitive {
|
||||||
ContentWarning(blurhash: attachmentData.blurhash, spoilerText: self.status.spoilerText) {
|
ContentWarning(blurhash: attachmentData.blurhash, spoilerText: self.status.spoilerText) {
|
||||||
Image(uiImage: uiImage)
|
Image(uiImage: uiImage)
|
||||||
.resizable()
|
.resizable()
|
||||||
|
|
|
@ -51,7 +51,7 @@ struct ImageRowAsync: View {
|
||||||
ZStack {
|
ZStack {
|
||||||
LazyImage(url: attachment.url) { state in
|
LazyImage(url: attachment.url) { state in
|
||||||
if let image = state.image {
|
if let image = state.image {
|
||||||
if self.statusViewModel.sensitive {
|
if self.statusViewModel.sensitive && !self.applicationState.showSensitive {
|
||||||
ZStack {
|
ZStack {
|
||||||
ContentWarning(blurhash: attachment.blurhash, spoilerText: self.statusViewModel.spoilerText) {
|
ContentWarning(blurhash: attachment.blurhash, spoilerText: self.statusViewModel.spoilerText) {
|
||||||
self.imageView(image: image)
|
self.imageView(image: image)
|
||||||
|
|
Loading…
Reference in New Issue