Ask for reviews after the user has used the app a bit
Browse files- PersonalGPT.xcodeproj/project.pbxproj +21 -1
- PersonalGPT.xcodeproj/xcuserdata/jeethu.xcuserdatad/xcschemes/xcschememanagement.plist +21 -0
- PersonalGPT/ChatBubble.swift +1 -1
- PersonalGPT/ChatState.swift +2 -0
- PersonalGPT/PersonalGPTApp.swift +10 -1
- PersonalGPT/Reviews/DeviceDetection.swift +113 -0
- PersonalGPT/Reviews/SKSReviewManager.swift +81 -0
- redpajama/ChatBackend.mm +12 -1
PersonalGPT.xcodeproj/project.pbxproj
CHANGED
|
@@ -36,6 +36,9 @@
|
|
| 36 |
48C554512A0FEE4800C96823 /* CodeBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C554502A0FEE4800C96823 /* CodeBlockView.swift */; };
|
| 37 |
48C554532A10C66A00C96823 /* AltCodeBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C554522A10C66A00C96823 /* AltCodeBlockView.swift */; };
|
| 38 |
48C7F7842A1CE2FD007C0A3D /* Markdown in Frameworks */ = {isa = PBXBuildFile; productRef = 48C7F7832A1CE2FD007C0A3D /* Markdown */; };
|
|
|
|
|
|
|
|
|
|
| 39 |
/* End PBXBuildFile section */
|
| 40 |
|
| 41 |
/* Begin PBXContainerItemProxy section */
|
|
@@ -111,6 +114,9 @@
|
|
| 111 |
48C5544E2A0FE32B00C96823 /* ParserResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserResult.swift; sourceTree = "<group>"; };
|
| 112 |
48C554502A0FEE4800C96823 /* CodeBlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeBlockView.swift; sourceTree = "<group>"; };
|
| 113 |
48C554522A10C66A00C96823 /* AltCodeBlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltCodeBlockView.swift; sourceTree = "<group>"; };
|
|
|
|
|
|
|
|
|
|
| 114 |
/* End PBXFileReference section */
|
| 115 |
|
| 116 |
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -121,6 +127,7 @@
|
|
| 121 |
48C7F7842A1CE2FD007C0A3D /* Markdown in Frameworks */,
|
| 122 |
48241DF32A13C6A4008FB7F5 /* Accelerate.framework in Frameworks */,
|
| 123 |
486279082A12463E00F45C4E /* Highlighter in Frameworks */,
|
|
|
|
| 124 |
);
|
| 125 |
runOnlyForDeploymentPostprocessing = 0;
|
| 126 |
};
|
|
@@ -169,6 +176,7 @@
|
|
| 169 |
48241DF12A13C6A4008FB7F5 /* Frameworks */ = {
|
| 170 |
isa = PBXGroup;
|
| 171 |
children = (
|
|
|
|
| 172 |
48241E092A157576008FB7F5 /* Accelerate.framework */,
|
| 173 |
48241DF22A13C6A4008FB7F5 /* Accelerate.framework */,
|
| 174 |
);
|
|
@@ -223,6 +231,7 @@
|
|
| 223 |
48B929A629ED80EA00607E43 /* PersonalGPT */ = {
|
| 224 |
isa = PBXGroup;
|
| 225 |
children = (
|
|
|
|
| 226 |
4825EA802A16AFEE00A02361 /* Settings */,
|
| 227 |
48B485AF2A1118A200F63766 /* Info.plist */,
|
| 228 |
48B929A729ED80EA00607E43 /* PersonalGPTApp.swift */,
|
|
@@ -269,6 +278,15 @@
|
|
| 269 |
path = PersonalGPTUITests;
|
| 270 |
sourceTree = "<group>";
|
| 271 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
/* End PBXGroup section */
|
| 273 |
|
| 274 |
/* Begin PBXNativeTarget section */
|
|
@@ -423,7 +441,9 @@
|
|
| 423 |
48C554512A0FEE4800C96823 /* CodeBlockView.swift in Sources */,
|
| 424 |
48B929AA29ED80EA00607E43 /* ContentView.swift in Sources */,
|
| 425 |
48055F732A0D2B070057C3BE /* ggml.c in Sources */,
|
|
|
|
| 426 |
48055F8F2A0F998F0057C3BE /* ChatBubble.swift in Sources */,
|
|
|
|
| 427 |
48055F8D2A0F96E10057C3BE /* TypingIndicator.swift in Sources */,
|
| 428 |
4825EA822A16B01000A02361 /* UserSettings.swift in Sources */,
|
| 429 |
48B929A829ED80EA00607E43 /* PersonalGPTApp.swift in Sources */,
|
|
@@ -526,7 +546,7 @@
|
|
| 526 |
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
| 527 |
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 528 |
MTL_FAST_MATH = YES;
|
| 529 |
-
ONLY_ACTIVE_ARCH =
|
| 530 |
SDKROOT = macosx;
|
| 531 |
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 532 |
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
|
|
|
| 36 |
48C554512A0FEE4800C96823 /* CodeBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C554502A0FEE4800C96823 /* CodeBlockView.swift */; };
|
| 37 |
48C554532A10C66A00C96823 /* AltCodeBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C554522A10C66A00C96823 /* AltCodeBlockView.swift */; };
|
| 38 |
48C7F7842A1CE2FD007C0A3D /* Markdown in Frameworks */ = {isa = PBXBuildFile; productRef = 48C7F7832A1CE2FD007C0A3D /* Markdown */; };
|
| 39 |
+
48C7F7862A1CEF2D007C0A3D /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48C7F7852A1CEF2C007C0A3D /* StoreKit.framework */; };
|
| 40 |
+
48C7F7882A1CEF95007C0A3D /* SKSReviewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C7F7872A1CEF95007C0A3D /* SKSReviewManager.swift */; };
|
| 41 |
+
48C7F78E2A1CFDAC007C0A3D /* DeviceDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C7F78D2A1CFDAC007C0A3D /* DeviceDetection.swift */; };
|
| 42 |
/* End PBXBuildFile section */
|
| 43 |
|
| 44 |
/* Begin PBXContainerItemProxy section */
|
|
|
|
| 114 |
48C5544E2A0FE32B00C96823 /* ParserResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserResult.swift; sourceTree = "<group>"; };
|
| 115 |
48C554502A0FEE4800C96823 /* CodeBlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeBlockView.swift; sourceTree = "<group>"; };
|
| 116 |
48C554522A10C66A00C96823 /* AltCodeBlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltCodeBlockView.swift; sourceTree = "<group>"; };
|
| 117 |
+
48C7F7852A1CEF2C007C0A3D /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.4.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; };
|
| 118 |
+
48C7F7872A1CEF95007C0A3D /* SKSReviewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SKSReviewManager.swift; sourceTree = "<group>"; };
|
| 119 |
+
48C7F78D2A1CFDAC007C0A3D /* DeviceDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceDetection.swift; sourceTree = "<group>"; };
|
| 120 |
/* End PBXFileReference section */
|
| 121 |
|
| 122 |
/* Begin PBXFrameworksBuildPhase section */
|
|
|
|
| 127 |
48C7F7842A1CE2FD007C0A3D /* Markdown in Frameworks */,
|
| 128 |
48241DF32A13C6A4008FB7F5 /* Accelerate.framework in Frameworks */,
|
| 129 |
486279082A12463E00F45C4E /* Highlighter in Frameworks */,
|
| 130 |
+
48C7F7862A1CEF2D007C0A3D /* StoreKit.framework in Frameworks */,
|
| 131 |
);
|
| 132 |
runOnlyForDeploymentPostprocessing = 0;
|
| 133 |
};
|
|
|
|
| 176 |
48241DF12A13C6A4008FB7F5 /* Frameworks */ = {
|
| 177 |
isa = PBXGroup;
|
| 178 |
children = (
|
| 179 |
+
48C7F7852A1CEF2C007C0A3D /* StoreKit.framework */,
|
| 180 |
48241E092A157576008FB7F5 /* Accelerate.framework */,
|
| 181 |
48241DF22A13C6A4008FB7F5 /* Accelerate.framework */,
|
| 182 |
);
|
|
|
|
| 231 |
48B929A629ED80EA00607E43 /* PersonalGPT */ = {
|
| 232 |
isa = PBXGroup;
|
| 233 |
children = (
|
| 234 |
+
48C7F78C2A1CFD9B007C0A3D /* Reviews */,
|
| 235 |
4825EA802A16AFEE00A02361 /* Settings */,
|
| 236 |
48B485AF2A1118A200F63766 /* Info.plist */,
|
| 237 |
48B929A729ED80EA00607E43 /* PersonalGPTApp.swift */,
|
|
|
|
| 278 |
path = PersonalGPTUITests;
|
| 279 |
sourceTree = "<group>";
|
| 280 |
};
|
| 281 |
+
48C7F78C2A1CFD9B007C0A3D /* Reviews */ = {
|
| 282 |
+
isa = PBXGroup;
|
| 283 |
+
children = (
|
| 284 |
+
48C7F7872A1CEF95007C0A3D /* SKSReviewManager.swift */,
|
| 285 |
+
48C7F78D2A1CFDAC007C0A3D /* DeviceDetection.swift */,
|
| 286 |
+
);
|
| 287 |
+
path = Reviews;
|
| 288 |
+
sourceTree = "<group>";
|
| 289 |
+
};
|
| 290 |
/* End PBXGroup section */
|
| 291 |
|
| 292 |
/* Begin PBXNativeTarget section */
|
|
|
|
| 441 |
48C554512A0FEE4800C96823 /* CodeBlockView.swift in Sources */,
|
| 442 |
48B929AA29ED80EA00607E43 /* ContentView.swift in Sources */,
|
| 443 |
48055F732A0D2B070057C3BE /* ggml.c in Sources */,
|
| 444 |
+
48C7F78E2A1CFDAC007C0A3D /* DeviceDetection.swift in Sources */,
|
| 445 |
48055F8F2A0F998F0057C3BE /* ChatBubble.swift in Sources */,
|
| 446 |
+
48C7F7882A1CEF95007C0A3D /* SKSReviewManager.swift in Sources */,
|
| 447 |
48055F8D2A0F96E10057C3BE /* TypingIndicator.swift in Sources */,
|
| 448 |
4825EA822A16B01000A02361 /* UserSettings.swift in Sources */,
|
| 449 |
48B929A829ED80EA00607E43 /* PersonalGPTApp.swift in Sources */,
|
|
|
|
| 546 |
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
| 547 |
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 548 |
MTL_FAST_MATH = YES;
|
| 549 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 550 |
SDKROOT = macosx;
|
| 551 |
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 552 |
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
PersonalGPT.xcodeproj/xcuserdata/jeethu.xcuserdatad/xcschemes/xcschememanagement.plist
CHANGED
|
@@ -4,6 +4,27 @@
|
|
| 4 |
<dict>
|
| 5 |
<key>SchemeUserState</key>
|
| 6 |
<dict>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
<key>PersonalGPT.xcscheme_^#shared#^_</key>
|
| 8 |
<dict>
|
| 9 |
<key>orderHint</key>
|
|
|
|
| 4 |
<dict>
|
| 5 |
<key>SchemeUserState</key>
|
| 6 |
<dict>
|
| 7 |
+
<key>DeviceKitPlayground (Playground) 1.xcscheme</key>
|
| 8 |
+
<dict>
|
| 9 |
+
<key>isShown</key>
|
| 10 |
+
<false/>
|
| 11 |
+
<key>orderHint</key>
|
| 12 |
+
<integer>2</integer>
|
| 13 |
+
</dict>
|
| 14 |
+
<key>DeviceKitPlayground (Playground) 2.xcscheme</key>
|
| 15 |
+
<dict>
|
| 16 |
+
<key>isShown</key>
|
| 17 |
+
<false/>
|
| 18 |
+
<key>orderHint</key>
|
| 19 |
+
<integer>3</integer>
|
| 20 |
+
</dict>
|
| 21 |
+
<key>DeviceKitPlayground (Playground).xcscheme</key>
|
| 22 |
+
<dict>
|
| 23 |
+
<key>isShown</key>
|
| 24 |
+
<false/>
|
| 25 |
+
<key>orderHint</key>
|
| 26 |
+
<integer>1</integer>
|
| 27 |
+
</dict>
|
| 28 |
<key>PersonalGPT.xcscheme_^#shared#^_</key>
|
| 29 |
<dict>
|
| 30 |
<key>orderHint</key>
|
PersonalGPT/ChatBubble.swift
CHANGED
|
@@ -25,7 +25,7 @@ struct ChatBubbleShape: Shape {
|
|
| 25 |
return Path()
|
| 26 |
}
|
| 27 |
}
|
| 28 |
-
|
| 29 |
private func leftBubble(in rect: CGRect) -> Path {
|
| 30 |
let width = rect.width
|
| 31 |
let height = rect.height
|
|
|
|
| 25 |
return Path()
|
| 26 |
}
|
| 27 |
}
|
| 28 |
+
|
| 29 |
private func leftBubble(in rect: CGRect) -> Path {
|
| 30 |
let width = rect.width
|
| 31 |
let height = rect.height
|
PersonalGPT/ChatState.swift
CHANGED
|
@@ -230,6 +230,8 @@ class ChatState: ObservableObject {
|
|
| 230 |
}
|
| 231 |
}
|
| 232 |
markFinish()
|
|
|
|
|
|
|
| 233 |
}
|
| 234 |
}
|
| 235 |
|
|
|
|
| 230 |
}
|
| 231 |
}
|
| 232 |
markFinish()
|
| 233 |
+
let messageLength = backend.getMessage().count
|
| 234 |
+
SKSReviewManager.requestReview(generatedTextLength: messageLength)
|
| 235 |
}
|
| 236 |
}
|
| 237 |
|
PersonalGPT/PersonalGPTApp.swift
CHANGED
|
@@ -34,7 +34,16 @@ struct PrivateAIChatApp: App {
|
|
| 34 |
func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool {
|
| 35 |
true
|
| 36 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
}
|
| 38 |
#else
|
| 39 |
-
class AppDelegate: NSObject, UIApplicationDelegate {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
#endif
|
|
|
|
| 34 |
func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool {
|
| 35 |
true
|
| 36 |
}
|
| 37 |
+
|
| 38 |
+
func applicationDidFinishLaunching(_: Notification) {
|
| 39 |
+
SKSReviewManager.incrementAppOpenCount()
|
| 40 |
+
}
|
| 41 |
}
|
| 42 |
#else
|
| 43 |
+
class AppDelegate: NSObject, UIApplicationDelegate {
|
| 44 |
+
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
| 45 |
+
SKSReviewManager.incrementAppOpenCount()
|
| 46 |
+
return true
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
#endif
|
PersonalGPT/Reviews/DeviceDetection.swift
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//
|
| 2 |
+
// DeviceDetection.swift
|
| 3 |
+
// PrivateAIChat
|
| 4 |
+
//
|
| 5 |
+
// Created by jrb16 on 23/05/2023.
|
| 6 |
+
//
|
| 7 |
+
#if os(iOS)
|
| 8 |
+
import UIKit
|
| 9 |
+
|
| 10 |
+
public extension UIDevice {
|
| 11 |
+
static let modelName: String = {
|
| 12 |
+
var systemInfo = utsname()
|
| 13 |
+
uname(&systemInfo)
|
| 14 |
+
let machineMirror = Mirror(reflecting: systemInfo.machine)
|
| 15 |
+
let identifier = machineMirror.children.reduce("") { identifier, element in
|
| 16 |
+
guard let value = element.value as? Int8, value != 0 else { return identifier }
|
| 17 |
+
return identifier + String(UnicodeScalar(UInt8(value)))
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
func mapToDevice(identifier: String) -> String { // swiftlint:disable:this cyclomatic_complexity
|
| 21 |
+
#if os(iOS)
|
| 22 |
+
switch identifier {
|
| 23 |
+
case "iPod5,1": return "iPod touch (5th generation)"
|
| 24 |
+
case "iPod7,1": return "iPod touch (6th generation)"
|
| 25 |
+
case "iPod9,1": return "iPod touch (7th generation)"
|
| 26 |
+
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4"
|
| 27 |
+
case "iPhone4,1": return "iPhone 4s"
|
| 28 |
+
case "iPhone5,1", "iPhone5,2": return "iPhone 5"
|
| 29 |
+
case "iPhone5,3", "iPhone5,4": return "iPhone 5c"
|
| 30 |
+
case "iPhone6,1", "iPhone6,2": return "iPhone 5s"
|
| 31 |
+
case "iPhone7,2": return "iPhone 6"
|
| 32 |
+
case "iPhone7,1": return "iPhone 6 Plus"
|
| 33 |
+
case "iPhone8,1": return "iPhone 6s"
|
| 34 |
+
case "iPhone8,2": return "iPhone 6s Plus"
|
| 35 |
+
case "iPhone9,1", "iPhone9,3": return "iPhone 7"
|
| 36 |
+
case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus"
|
| 37 |
+
case "iPhone10,1", "iPhone10,4": return "iPhone 8"
|
| 38 |
+
case "iPhone10,2", "iPhone10,5": return "iPhone 8 Plus"
|
| 39 |
+
case "iPhone10,3", "iPhone10,6": return "iPhone X"
|
| 40 |
+
case "iPhone11,2": return "iPhone XS"
|
| 41 |
+
case "iPhone11,4", "iPhone11,6": return "iPhone XS Max"
|
| 42 |
+
case "iPhone11,8": return "iPhone XR"
|
| 43 |
+
case "iPhone12,1": return "iPhone 11"
|
| 44 |
+
case "iPhone12,3": return "iPhone 11 Pro"
|
| 45 |
+
case "iPhone12,5": return "iPhone 11 Pro Max"
|
| 46 |
+
case "iPhone13,1": return "iPhone 12 mini"
|
| 47 |
+
case "iPhone13,2": return "iPhone 12"
|
| 48 |
+
case "iPhone13,3": return "iPhone 12 Pro"
|
| 49 |
+
case "iPhone13,4": return "iPhone 12 Pro Max"
|
| 50 |
+
case "iPhone14,4": return "iPhone 13 mini"
|
| 51 |
+
case "iPhone14,5": return "iPhone 13"
|
| 52 |
+
case "iPhone14,2": return "iPhone 13 Pro"
|
| 53 |
+
case "iPhone14,3": return "iPhone 13 Pro Max"
|
| 54 |
+
case "iPhone14,7": return "iPhone 14"
|
| 55 |
+
case "iPhone14,8": return "iPhone 14 Plus"
|
| 56 |
+
case "iPhone15,2": return "iPhone 14 Pro"
|
| 57 |
+
case "iPhone15,3": return "iPhone 14 Pro Max"
|
| 58 |
+
case "iPhone8,4": return "iPhone SE"
|
| 59 |
+
case "iPhone12,8": return "iPhone SE (2nd generation)"
|
| 60 |
+
case "iPhone14,6": return "iPhone SE (3rd generation)"
|
| 61 |
+
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return "iPad 2"
|
| 62 |
+
case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad (3rd generation)"
|
| 63 |
+
case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad (4th generation)"
|
| 64 |
+
case "iPad6,11", "iPad6,12": return "iPad (5th generation)"
|
| 65 |
+
case "iPad7,5", "iPad7,6": return "iPad (6th generation)"
|
| 66 |
+
case "iPad7,11", "iPad7,12": return "iPad (7th generation)"
|
| 67 |
+
case "iPad11,6", "iPad11,7": return "iPad (8th generation)"
|
| 68 |
+
case "iPad12,1", "iPad12,2": return "iPad (9th generation)"
|
| 69 |
+
case "iPad13,18", "iPad13,19": return "iPad (10th generation)"
|
| 70 |
+
case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air"
|
| 71 |
+
case "iPad5,3", "iPad5,4": return "iPad Air 2"
|
| 72 |
+
case "iPad11,3", "iPad11,4": return "iPad Air (3rd generation)"
|
| 73 |
+
case "iPad13,1", "iPad13,2": return "iPad Air (4th generation)"
|
| 74 |
+
case "iPad13,16", "iPad13,17": return "iPad Air (5th generation)"
|
| 75 |
+
case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad mini"
|
| 76 |
+
case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad mini 2"
|
| 77 |
+
case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad mini 3"
|
| 78 |
+
case "iPad5,1", "iPad5,2": return "iPad mini 4"
|
| 79 |
+
case "iPad11,1", "iPad11,2": return "iPad mini (5th generation)"
|
| 80 |
+
case "iPad14,1", "iPad14,2": return "iPad mini (6th generation)"
|
| 81 |
+
case "iPad6,3", "iPad6,4": return "iPad Pro (9.7-inch)"
|
| 82 |
+
case "iPad7,3", "iPad7,4": return "iPad Pro (10.5-inch)"
|
| 83 |
+
case "iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4": return "iPad Pro (11-inch) (1st generation)"
|
| 84 |
+
case "iPad8,9", "iPad8,10": return "iPad Pro (11-inch) (2nd generation)"
|
| 85 |
+
case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7": return "iPad Pro (11-inch) (3rd generation)"
|
| 86 |
+
case "iPad14,3", "iPad14,4": return "iPad Pro (11-inch) (4th generation)"
|
| 87 |
+
case "iPad6,7", "iPad6,8": return "iPad Pro (12.9-inch) (1st generation)"
|
| 88 |
+
case "iPad7,1", "iPad7,2": return "iPad Pro (12.9-inch) (2nd generation)"
|
| 89 |
+
case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8": return "iPad Pro (12.9-inch) (3rd generation)"
|
| 90 |
+
case "iPad8,11", "iPad8,12": return "iPad Pro (12.9-inch) (4th generation)"
|
| 91 |
+
case "iPad13,8", "iPad13,9", "iPad13,10", "iPad13,11": return "iPad Pro (12.9-inch) (5th generation)"
|
| 92 |
+
case "iPad14,5", "iPad14,6": return "iPad Pro (12.9-inch) (6th generation)"
|
| 93 |
+
case "AppleTV5,3": return "Apple TV"
|
| 94 |
+
case "AppleTV6,2": return "Apple TV 4K"
|
| 95 |
+
case "AudioAccessory1,1": return "HomePod"
|
| 96 |
+
case "AudioAccessory5,1": return "HomePod mini"
|
| 97 |
+
case "i386", "x86_64", "arm64": return "Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "iOS"))"
|
| 98 |
+
default: return identifier
|
| 99 |
+
}
|
| 100 |
+
#elseif os(tvOS)
|
| 101 |
+
switch identifier {
|
| 102 |
+
case "AppleTV5,3": return "Apple TV 4"
|
| 103 |
+
case "AppleTV6,2": return "Apple TV 4K"
|
| 104 |
+
case "i386", "x86_64": return "Simulator \(mapToDevice(identifier: ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "tvOS"))"
|
| 105 |
+
default: return identifier
|
| 106 |
+
}
|
| 107 |
+
#endif
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
return mapToDevice(identifier: identifier)
|
| 111 |
+
}()
|
| 112 |
+
}
|
| 113 |
+
#endif
|
PersonalGPT/Reviews/SKSReviewManager.swift
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//
|
| 2 |
+
// SKSReviewManager.swift
|
| 3 |
+
// PrivateAIChat
|
| 4 |
+
//
|
| 5 |
+
// Created by jrb16 on 23/05/2023.
|
| 6 |
+
//
|
| 7 |
+
|
| 8 |
+
import Foundation
|
| 9 |
+
|
| 10 |
+
import StoreKit
|
| 11 |
+
class SKSReviewManager {
|
| 12 |
+
private static let instance = SKSReviewManager()
|
| 13 |
+
static let openCountKey = "open_count_config"
|
| 14 |
+
static let replyCountKey = "reply_count_config"
|
| 15 |
+
static let totalGeneratedTextLengthKey = "generated_text_length_config"
|
| 16 |
+
static let lastVersionPromptedForReviewKey = "last_version_prompted_config"
|
| 17 |
+
|
| 18 |
+
var sharedInstance: SKSReviewManager {
|
| 19 |
+
.instance
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
static func incrementAppOpenCount() { // called from appdelegate didfinishLaunchingWithOptions:
|
| 23 |
+
let ud = UserDefaults.standard
|
| 24 |
+
var count = ud.integer(forKey: Self.openCountKey)
|
| 25 |
+
count += 1
|
| 26 |
+
ud.set(count, forKey: Self.openCountKey)
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
static func requestReview(generatedTextLength: Int) {
|
| 30 |
+
let ud = UserDefaults.standard
|
| 31 |
+
let count = ud.integer(forKey: Self.openCountKey)
|
| 32 |
+
let lastVersionPromptedForReview = ud.string(forKey: Self.lastVersionPromptedForReviewKey)
|
| 33 |
+
|
| 34 |
+
// Increment the number of replies
|
| 35 |
+
var replyCount = ud.integer(forKey: Self.replyCountKey)
|
| 36 |
+
replyCount += 1
|
| 37 |
+
ud.set(replyCount, forKey: Self.replyCountKey)
|
| 38 |
+
|
| 39 |
+
// Increment the generated text length
|
| 40 |
+
var totalGeneratedTextLength = ud.integer(forKey: Self.totalGeneratedTextLengthKey)
|
| 41 |
+
totalGeneratedTextLength += generatedTextLength
|
| 42 |
+
ud.set(totalGeneratedTextLength, forKey: Self.totalGeneratedTextLengthKey)
|
| 43 |
+
|
| 44 |
+
// Get the current bundle version for the app.
|
| 45 |
+
let infoDictionaryKey = kCFBundleVersionKey as String
|
| 46 |
+
guard let currentVersion = Bundle.main.object(forInfoDictionaryKey: infoDictionaryKey) as? String
|
| 47 |
+
else { fatalError("Expected to find a bundle version in the info dictionary.") }
|
| 48 |
+
// Verify the user completes the process several times and doesn’t receive a prompt for this app version.
|
| 49 |
+
if count >= 4, replyCount >= 8, totalGeneratedTextLength >= 256, currentVersion != lastVersionPromptedForReview, shouldRequestReview() {
|
| 50 |
+
Task { @MainActor [] in
|
| 51 |
+
// Delay for two seconds to avoid interrupting the person using the app.
|
| 52 |
+
// Use the equation n * 10^9 to convert seconds to nanoseconds.
|
| 53 |
+
try? await Task.sleep(nanoseconds: UInt64(2e9))
|
| 54 |
+
|
| 55 |
+
#if os(iOS)
|
| 56 |
+
let allScenes = UIApplication.shared.connectedScenes
|
| 57 |
+
let scene = allScenes.first { $0.activationState == .foregroundActive }
|
| 58 |
+
|
| 59 |
+
if let windowScene = scene as? UIWindowScene {
|
| 60 |
+
SKStoreReviewController.requestReview(in: windowScene)
|
| 61 |
+
UserDefaults.standard.set(currentVersion, forKey: Self.lastVersionPromptedForReviewKey)
|
| 62 |
+
}
|
| 63 |
+
#else
|
| 64 |
+
SKStoreReviewController.requestReview()
|
| 65 |
+
#endif
|
| 66 |
+
}
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
private static func shouldRequestReview() -> Bool {
|
| 71 |
+
#if os(iOS)
|
| 72 |
+
let verboteniPhones = ["iPhone XS", "iPhone XS Max", "iPhone XR", "iPhone 11", "iPhone 11 Pro", "iPhone 11 Pro Max", "iPhone 12 mini", "iPhone 12", "iPhone 12 Pro", "iPhone 12 Pro Max"]
|
| 73 |
+
let verboteniPads = ["iPad (8th generation)", "iPad mini (5th generation)", "iPad Air (3rd generation)"]
|
| 74 |
+
let modelName = UIDevice.modelName
|
| 75 |
+
if verboteniPhones.contains(modelName) || verboteniPads.contains(modelName) {
|
| 76 |
+
return false
|
| 77 |
+
}
|
| 78 |
+
#endif
|
| 79 |
+
return true
|
| 80 |
+
}
|
| 81 |
+
}
|
redpajama/ChatBackend.mm
CHANGED
|
@@ -442,10 +442,21 @@ CPPChatBackend::~CPPChatBackend() {
|
|
| 442 |
backend->decode(temperature, topK, topP, enable_mirostat);
|
| 443 |
}
|
| 444 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
- (NSString*)getMessage {
|
| 446 |
CPPChatBackend* backend = [self getBackendInstance];
|
| 447 |
std::string message = backend->getMessage();
|
| 448 |
-
|
|
|
|
|
|
|
| 449 |
}
|
| 450 |
|
| 451 |
- (bool)stopped {
|
|
|
|
| 442 |
backend->decode(temperature, topK, topP, enable_mirostat);
|
| 443 |
}
|
| 444 |
|
| 445 |
+
- (NSString *)removeSuffixes:(NSArray *)suffixes fromString:(NSString *)string {
|
| 446 |
+
for (NSString *suffix in suffixes) {
|
| 447 |
+
if ([string hasSuffix:suffix]) {
|
| 448 |
+
string = [string substringToIndex:string.length - suffix.length];
|
| 449 |
+
}
|
| 450 |
+
}
|
| 451 |
+
return string;
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
- (NSString*)getMessage {
|
| 455 |
CPPChatBackend* backend = [self getBackendInstance];
|
| 456 |
std::string message = backend->getMessage();
|
| 457 |
+
NSString* msg = [NSString stringWithUTF8String:message.c_str()];
|
| 458 |
+
NSArray *suffixes = @[@"\n", @"<human", @"<human>", @"<bot", @"<bot>"];
|
| 459 |
+
return [self removeSuffixes:suffixes fromString:msg];
|
| 460 |
}
|
| 461 |
|
| 462 |
- (bool)stopped {
|