From cd1067345d82942c79032d29dc8850ad905cc7d6 Mon Sep 17 00:00:00 2001 From: Amit Samant Date: Thu, 27 Oct 2022 23:57:40 +0530 Subject: [PATCH] Intermidiate code added --- .../api/amplifyDatasource/schema.graphql | 1 + amplify/generated/models/AWSCategory.swift | 8 +-- .../generated/models/AWSTweet+Schema.swift | 2 +- brain-marks.xcodeproj/project.pbxproj | 1 - brain-marks/Add/AddURLViewModel.swift | 64 +++++++++++++++---- brain-marks/Models/ReturnedTweet.swift | 16 ++++- brain-marks/Models/Tweet.swift | 11 ++++ brain-marks/Tweets/Views/TweetCard.swift | 1 + brain-marks/Utilities/RequestBuilder.swift | 2 +- 9 files changed, 85 insertions(+), 21 deletions(-) diff --git a/amplify/backend/api/amplifyDatasource/schema.graphql b/amplify/backend/api/amplifyDatasource/schema.graphql index 0f8c922..9cdb8ab 100644 --- a/amplify/backend/api/amplifyDatasource/schema.graphql +++ b/amplify/backend/api/amplifyDatasource/schema.graphql @@ -9,6 +9,7 @@ type AWSTweet @model { photosURL: [String] category: AWSCategory @connection(name: "CategorizedTweet") userVerified: Boolean + quoteTweet: AWSTweet @belongsTo } type AWSCategory @model { diff --git a/amplify/generated/models/AWSCategory.swift b/amplify/generated/models/AWSCategory.swift index 4ec98f5..d14f644 100644 --- a/amplify/generated/models/AWSCategory.swift +++ b/amplify/generated/models/AWSCategory.swift @@ -7,16 +7,14 @@ public struct AWSCategory: Model { public var name: String public var imageName: String? public var tweets: List? - public var categoryThumbnail: String? public init(id: String = UUID().uuidString, name: String, - imageName: String? = "folder", - tweets: List? = [] - ) { + imageName: String? = nil, + tweets: List? = []) { self.id = id self.name = name self.imageName = imageName self.tweets = tweets } -} +} \ No newline at end of file diff --git a/amplify/generated/models/AWSTweet+Schema.swift b/amplify/generated/models/AWSTweet+Schema.swift index 458e3bf..a1cd453 100644 --- a/amplify/generated/models/AWSTweet+Schema.swift +++ b/amplify/generated/models/AWSTweet+Schema.swift @@ -34,7 +34,7 @@ extension AWSTweet { .field(aWSTweet.authorUsername, is: .optional, ofType: .string), .field(aWSTweet.profileImageURL, is: .optional, ofType: .string), .field(aWSTweet.photosURL, is: .optional, ofType: .embeddedCollection(of: String.self)), - .belongsTo(aWSTweet.category, is: .optional, ofType: AWSCategory.self, targetName: "awsTweetCategoryId"), + .belongsTo(aWSTweet.category, is: .optional, ofType: AWSCategory.self, targetName: "aWSTweetCategoryId"), .field(aWSTweet.userVerified, is: .optional, ofType: .bool) ) } diff --git a/brain-marks.xcodeproj/project.pbxproj b/brain-marks.xcodeproj/project.pbxproj index d2323d1..2c388fc 100644 --- a/brain-marks.xcodeproj/project.pbxproj +++ b/brain-marks.xcodeproj/project.pbxproj @@ -722,7 +722,6 @@ /* Begin PBXShellScriptBuildPhase section */ FFEBBB802622755F000F475F /* ShellScript */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); diff --git a/brain-marks/Add/AddURLViewModel.swift b/brain-marks/Add/AddURLViewModel.swift index 534db3d..5b6d0f8 100644 --- a/brain-marks/Add/AddURLViewModel.swift +++ b/brain-marks/Add/AddURLViewModel.swift @@ -35,8 +35,9 @@ final class AddURLViewModel: ObservableObject { do { let result = try JSONDecoder().decode(Response.self, from: data) - return createTweet(result) + return await createTweet(result) } catch { + debugPrint(error) throw HttpError.cantDecode } } else { @@ -71,7 +72,22 @@ final class AddURLViewModel: ObservableObject { return completeURL } - private func createTweet (_ result: Response) -> ReturnedTweet { + private func getQuoteTweetLink(fromTweetText text: String) -> URL? { + do { + let regex = try NSRegularExpression(pattern: #"http(?:s)?:\/\/t\.co\/([a-zA-Z0-9_]+)"#) + guard let linkMatch = regex.firstMatch(in: text, range: NSRange(location: 0, length: text.utf16.count)) else { + return nil + } + let linkString = (text as NSString).substring(with: linkMatch.range) + return URL(string: linkString) + } catch { + assertionFailure(error.localizedDescription) + return nil + } + + } + + private func createTweet (_ result: Response) async -> ReturnedTweet { let user = result.includes.users.first let authorName = user?.name ?? "" @@ -88,16 +104,40 @@ final class AddURLViewModel: ObservableObject { } } - let tweetToSave = ReturnedTweet( - id: result.data[0].id, - text: result.data[0].text, - timeStamp: result.data[0].created_at, - authorName: authorName, - authorUsername: authorUsername, - profileImageURL: profileImageURL, - userVerified: userVerified, - photosUrl: photoUrl) + lazy var plainTweet: ReturnedTweet = { + ReturnedTweet( + id: result.data[0].id, + text: result.data[0].text, + timeStamp: result.data[0].created_at, + authorName: authorName, + authorUsername: authorUsername, + profileImageURL: profileImageURL, + userVerified: userVerified, + photosUrl: photoUrl, + quoteTweet: nil + ) + }() - return tweetToSave + guard let quoteTweetURL = getQuoteTweetLink(fromTweetText: result.data[0].text) else { + return plainTweet + } + + do { + let quoteTweet = try await fetchTweet(url: quoteTweetURL.absoluteString) + return ReturnedTweet( + id: result.data[0].id, + text: result.data[0].text, + timeStamp: result.data[0].created_at, + authorName: authorName, + authorUsername: authorUsername, + profileImageURL: profileImageURL, + userVerified: userVerified, + photosUrl: photoUrl, + quoteTweet: quoteTweet + ) + } catch { + debugPrint(error.localizedDescription) + return plainTweet + } } } diff --git a/brain-marks/Models/ReturnedTweet.swift b/brain-marks/Models/ReturnedTweet.swift index 10a365e..0c16a26 100644 --- a/brain-marks/Models/ReturnedTweet.swift +++ b/brain-marks/Models/ReturnedTweet.swift @@ -7,7 +7,20 @@ import Foundation -struct ReturnedTweet: Codable { +class ReturnedTweet: Codable { + + init(id: String, text: String, timeStamp: String, authorName: String, authorUsername: String, profileImageURL: String, userVerified: Bool, photosUrl: [String], quoteTweet: ReturnedTweet? = nil) { + self.id = id + self.text = text + self.timeStamp = timeStamp + self.authorName = authorName + self.authorUsername = authorUsername + self.profileImageURL = profileImageURL + self.userVerified = userVerified + self.photosUrl = photosUrl + self.quoteTweet = quoteTweet + } + let id: String let text: String let timeStamp: String @@ -18,4 +31,5 @@ struct ReturnedTweet: Codable { let userVerified: Bool let photosUrl : [String] + let quoteTweet: ReturnedTweet? } diff --git a/brain-marks/Models/Tweet.swift b/brain-marks/Models/Tweet.swift index a7cb55e..1058d05 100644 --- a/brain-marks/Models/Tweet.swift +++ b/brain-marks/Models/Tweet.swift @@ -7,8 +7,19 @@ import Foundation +enum ReferencedTweetType: String, Codable { + case replied_to + case quoted +} + +struct ReferencedTweet: Codable { + let type: ReferencedTweetType + let id: String +} + struct Tweet: Codable { let id: String let text: String let created_at: String + let referenced_tweets: [ReferencedTweet] } diff --git a/brain-marks/Tweets/Views/TweetCard.swift b/brain-marks/Tweets/Views/TweetCard.swift index 81b2654..9ad99bc 100644 --- a/brain-marks/Tweets/Views/TweetCard.swift +++ b/brain-marks/Tweets/Views/TweetCard.swift @@ -20,6 +20,7 @@ struct TweetCard: View { TweetBodyView(tweetBody: tweet.text!.removingUrls()) } TweetPhotosView(width: 60, maxWidth: 400, photosURL: tweet.photosURL ?? [String]()) + if let timeStamp = tweet.timeStamp { TimeStampView(timeStamp: timeStamp) } diff --git a/brain-marks/Utilities/RequestBuilder.swift b/brain-marks/Utilities/RequestBuilder.swift index d1be501..25636d7 100644 --- a/brain-marks/Utilities/RequestBuilder.swift +++ b/brain-marks/Utilities/RequestBuilder.swift @@ -46,7 +46,7 @@ private extension RequestBuilder { components.path = "/2/tweets" components.queryItems = [ URLQueryItem(name: "ids", value: id), - URLQueryItem(name: "expansions", value: "author_id,attachments.media_keys"), + URLQueryItem(name: "expansions", value: "author_id,attachments.media_keys,referenced_tweets.id"), URLQueryItem(name: "tweet.fields", value: "created_at"), URLQueryItem(name: "user.fields", value: "profile_image_url,verified"), URLQueryItem(name: "media.fields", value: "preview_image_url,public_metrics,type,url")