Skip to content

Commit

Permalink
Implement tweet chains by replies
Browse files Browse the repository at this point in the history
  • Loading branch information
koher committed Dec 29, 2017
1 parent 607f4c1 commit becf67a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
18 changes: 12 additions & 6 deletions Sources/TweetupKit/Async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,33 @@ public func sync<T, R>(operation: (@escaping (T, @escaping (() throws -> R) -> (
}
}

internal func repeated<T, R1, R2>(operation: @escaping (T, R1?) -> Promise<() throws -> R2>, convert: @escaping (R2) -> R1, interval: TimeInterval? = nil) -> ([T]) -> Promise<() throws -> [R2]> {
return { values in
_repeat(operation: operation, for: values[...], convert: convert, interval: interval)
}
}

internal func repeated<T, R>(operation: @escaping (T) -> Promise<() throws -> R>, interval: TimeInterval? = nil) -> ([T]) -> Promise<() throws -> [R]> {
return { values in
_repeat(operation: operation, for: values[...], interval: interval)
_repeat(operation: { r, _ in operation(r) }, for: values[...], convert: { $0 }, interval: interval)
}
}

private func _repeat<T, R>(operation: @escaping (T) -> Promise<() throws -> R>, for values: ArraySlice<T>, interval: TimeInterval?, results: [R] = []) -> Promise<() throws -> [R]> {
private func _repeat<T, R1, R2>(operation: @escaping (T, R1?) -> Promise<() throws -> R2>, for values: ArraySlice<T>, convert: @escaping (R2) -> R1, interval: TimeInterval?, results: [R2] = []) -> Promise<() throws -> [R2]> {
let (headOrNil, tail) = values.headAndTail
guard let head = headOrNil else {
return Promise { results }
}

let resultPromise: Promise<() throws -> R>
let resultPromise: Promise<() throws -> R2>
if let interval = interval, !tail.isEmpty {
resultPromise = wait(operation(head), for: interval)
resultPromise = wait(operation(head, results.last.map(convert)), for: interval)
} else {
resultPromise = operation(head)
resultPromise = operation(head, results.last.map(convert))
}

return resultPromise.flatMap { getResult in
_repeat(operation: operation, for: tail, interval: interval, results: results + [try getResult()])
_repeat(operation: operation, for: tail, convert: convert, interval: interval, results: results + [try getResult()])
}
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/TweetupKit/Speaker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ public struct Speaker {
}

public func post(tweets: [Tweet], interval: TimeInterval?) -> Promise<() throws -> [PostResponse]> {
return repeated(operation: post, interval: interval)(tweets)
return repeated(operation: post, convert: { $0.statusId }, interval: interval)(tweets)
}

public func post(tweet: Tweet) -> Promise<() throws -> PostResponse> {
public func post(tweet: Tweet, replyingTo statusId: String?) -> Promise<() throws -> PostResponse> {
guard let twitterCredential = twitterCredential else {
return Promise { throw SpeakerError.noTwitterCredential }
}
Expand Down Expand Up @@ -76,7 +76,7 @@ public struct Speaker {
} else {
mediaId = nil
}
return Twitter.update(status: status, mediaId: mediaId, credential: twitterCredential).map { PostResponse(try $0()) }
return Twitter.update(status: status, mediaId: mediaId, inReplyToStatusId: statusId, credential: twitterCredential).map { PostResponse(try $0()) }
}.map { getResponse in
try getResponse()
}
Expand Down

0 comments on commit becf67a

Please sign in to comment.