Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add paste button for token in advanced mode [Proper PR] #538

Open
wants to merge 1 commit into
base: alpha
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,9 @@
},
"If it's taking too long, tap cancel and try again." : {

},
"If it's taking too long, tap cancel and try again. Or you can press the button below to paste the URL reddit redirected you to." : {

},
"Import Settings" : {
"localizations" : {
Expand Down Expand Up @@ -2683,6 +2686,9 @@
}
}
}
},
"Paste" : {

},
"Paste here the app ID" : {
"localizations" : {
Expand Down Expand Up @@ -2718,6 +2724,9 @@
},
"Pause background audio on fullscreen" : {

},
"Pinned" : {

},
"Placeholder image" : {
"localizations" : {
Expand Down Expand Up @@ -3724,6 +3733,9 @@
},
"The authorization flow didn't work. Please tap the error button and try again or use another credential." : {

},
"The clipboard contains no URLs. Make sure to have properly copied the URL, tap the error button and try again." : {

},
"The credentials seem to be valid, but we need you to authorize the credentials to access your account *(yeah, it sounds redundand, sorry)*." : {

Expand Down Expand Up @@ -4357,4 +4369,4 @@
}
},
"version" : "1.0"
}
}
14 changes: 12 additions & 2 deletions winston/models/RedditAPI/RedditAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,9 @@ class RedditAPI {
return false
}

func getAuthCodeFromURL(_ rawUrl: URL) -> String? {
if let url = URL(string: rawUrl.absoluteString.replacingOccurrences(of: "winstonapp://", with: "https://app.winston.cafe/")), url.lastPathComponent == "auth-success", let query = URLComponents(url: url, resolvingAgainstBaseURL: false), let state = query.queryItems?.first(where: { $0.name == "state" })?.value, let code = query.queryItems?.first(where: { $0.name == "code" })?.value, state == lastAuthState {
/// This function is preferred when the URL to be evaluated is already the app.winston.cafe URL with https scheme
func getAuthCodeFromURL(_ url: URL) -> String? {
if ((url.scheme == "https" && url.host() == "app.winston.cafe") || url.scheme == "winstonapp"), url.lastPathComponent == "auth-success", let query = URLComponents(url: url, resolvingAgainstBaseURL: false), let state = query.queryItems?.first(where: { $0.name == "state" })?.value, let code = query.queryItems?.first(where: { $0.name == "code" })?.value, state == lastAuthState {
// let res = await injectFirstAccessTokenInto(&credential, authCode: code)
// lastAuthState = nil
// return res
Expand All @@ -193,6 +194,15 @@ class RedditAPI {
return nil
}
}

// /// This function is preferred when the URL to be evaluated is already the app.winston.cafe URL with https scheme
// func getAuthCodeFromURLWithHTTPS(_ url: URL) -> String? {
// if url.lastPathComponent == "auth-success", let query = URLComponents(url: url, resolvingAgainstBaseURL: false), let state = query.queryItems?.first(where: { $0.name == "state" })?.value, let code = query.queryItems?.first(where: { $0.name == "code" })?.value, state == lastAuthState {
// return code
// } else {
// return nil
// }
// }

func getAuthorizationCodeURL(_ appID: String) -> URL {
let response_type: String = "code"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct EditCredWhatToDoBannerBody: View, Equatable {
var advanced: Bool
var openURL: () -> ()
@Binding var completionStatus: EditCredWhatToDoBanner.BannerStatus
@Binding var draftCredential: RedditCredential
@Environment(\.colorScheme) private var cs

var body: some View {
Expand All @@ -35,7 +36,7 @@ struct EditCredWhatToDoBannerBody: View, Equatable {
Text("The credentials seem to be valid, but we need you to authorize the credentials to access your account *(yeah, it sounds redundand, sorry)*.").opacity(0.8)
PressableButton(animation: .easeOut(duration: 0.2)) {
switch completionStatus {
case .fetchError, .wrongUrl, .waitingForCallback: withAnimation(.spring) { completionStatus = .onHold }
case .fetchError, .wrongUrl, .noUrl, .waitingForCallback: withAnimation(.spring) { completionStatus = .onHold }
case .success: break
case .onHold:
withAnimation(.spring) { completionStatus = .waitingForCallback }
Expand All @@ -54,7 +55,7 @@ struct EditCredWhatToDoBannerBody: View, Equatable {
case .waitingForCallback:
ProgressView()
Text("Cancel")
case .wrongUrl, .fetchError:
case .wrongUrl, .fetchError, .noUrl:
BetterLottieView("error", size: 19, initialDelay: 0.2, color: .white)
Text("Something went wrong")
}
Expand All @@ -76,16 +77,68 @@ struct EditCredWhatToDoBannerBody: View, Equatable {
Group {
switch completionStatus {
case .onHold, .success: EmptyView()
case .waitingForCallback: Text("If it's taking too long, tap cancel and try again.")
case .waitingForCallback:
if advanced {
Text("If it's taking too long, tap cancel and try again. Or you can press the button below to paste the URL reddit redirected you to.")
} else {
Text("If it's taking too long, tap cancel and try again.")
}
case .wrongUrl: Text("Something wrong with the information we received from Reddit. Please tap the error button and try again.")
case .fetchError: Text("The authorization flow didn't work. Please tap the error button and try again or use another credential.")
case .noUrl: Text("The clipboard contains no URLs. Make sure to have properly copied the URL, tap the error button and try again.")
}
}
.opacity(0.65)
.fontSize(14)
.transition(.scaleAndBlur)
.id("details-what-to-do-\(completionStatus.rawValue)")

if advanced && (completionStatus == .waitingForCallback) {
VStack(alignment: .leading/*, spacing: 12*/) {
PressableButton(animation: .easeOut(duration: 0.2)) {
if UIPasteboard.general.hasURLs {
let url = UIPasteboard.general.url!

Task(priority: .background) {
var tempCred = draftCredential
if let authToken = RedditAPI.shared.getAuthCodeFromURL(url) {
let success = await RedditAPI.shared.injectFirstAccessTokenInto(&tempCred, authCode: authToken)
await MainActor.run {
withAnimation(.spring) {
completionStatus = success ? .success : .fetchError
}
if completionStatus == .success {
doThisAfter(2) {
withAnimation { draftCredential = tempCred }
}
}
}
} else {
await MainActor.run {
withAnimation(.spring) {
completionStatus = .wrongUrl
}
}
}
}
} else {
completionStatus = .noUrl
}
} label: { pressed in
HStack(spacing: 4) {
Image(systemName: "doc.on.clipboard.fill")
Text("Paste")
}
.fontSize(16, .semibold)
.padding(.horizontal, 16)
.padding(.vertical, 12)
.frame(maxWidth: .infinity)
.background(RR(12, .pink))
.foregroundStyle(Color.primary)
.brightness(!pressed ? 0 : cs == .dark ? 0.05 : -0.05)
}
}
}
}
.fontSize(15)
.animation(.spring, value: completionStatus)
Expand All @@ -104,7 +157,7 @@ struct EditCredWhatToDoBanner: View, Equatable {
@Environment(\.openURL) private var openURL
@State private var completionStatus: BannerStatus = .onHold

enum BannerStatus: String { case fetchError, wrongUrl, success, waitingForCallback, onHold }
enum BannerStatus: String { case fetchError, wrongUrl, success, waitingForCallback, onHold, noUrl }

var body: some View {
let status = draftCredential.validationStatus
Expand All @@ -122,7 +175,7 @@ struct EditCredWhatToDoBanner: View, Equatable {

EditCredWhatToDoBannerBody(status: status, advanced: advanced, openURL: {
openURL(RedditAPI.shared.getAuthorizationCodeURL(draftCredential.apiAppID))
}, completionStatus: $completionStatus).equatable()
}, completionStatus: $completionStatus, draftCredential: $draftCredential).equatable()
.transition(.identity)
.id(statusMeta.label)
.padding(EdgeInsets(top: 0, leading: padding.leading, bottom: padding.bottom, trailing: padding.trailing))
Expand Down