diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..eed88ef68 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,82 @@ +name: CI + +on: + # Triggers the workflow on any pull request and push to develop + push: + branches: [ develop ] + pull_request: + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + build: + name: Build + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + + # Common cache + # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job + - uses: actions/cache@v2 + with: + path: Pods + key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-pods- + - uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gems- + + # Common setup + # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job + - name: Bundle install + run: | + bundle config path vendor/bundle + bundle install --jobs 4 --retry 3 + - name: Use right MatrixKit and MatrixSDK versions + run: bundle exec fastlane point_dependencies_to_pending_releases + + # Main step + - name: Build iOS simulator + run: bundle exec fastlane build + + + tests: + name: Tests + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + + # Common cache + # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job + - uses: actions/cache@v2 + with: + path: Pods + key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-pods- + - uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gems- + + # Common setup + # Note: GH actions do not support yaml anchor yet. We need to duplicate this for every job + - name: Bundle install + run: | + bundle config path vendor/bundle + bundle install --jobs 4 --retry 3 + - name: Use right MatrixKit and MatrixSDK versions + run: bundle exec fastlane point_dependencies_to_pending_releases + + # Main step + - name: Unit tests + run: bundle exec fastlane test diff --git a/CHANGES.rst b/CHANGES.rst index be23b55d5..a2772fd98 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -16,6 +16,8 @@ Changes to be released in next version 🐛 Bugfix * PublicRoomsDirectoryDataSource: Fix search when NSFW filter is off. + * RoomVC: Fix navigation issue when a room left. + * RoomVC: Fix a crash when scroll to bottom tapped on a left room. ⚠️ API Changes * @@ -24,7 +26,7 @@ Changes to be released in next version * 🧱 Build - * + * GH Actions: Start using them for CI to check simulator build and tests. Others * diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift index 5348b9ab1..44a46cbd0 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinatorBridgePresenter.swift @@ -33,6 +33,12 @@ final class RoomInfoCoordinatorBridgePresenter: NSObject { private let coordinatorParameters: RoomInfoCoordinatorParameters private var coordinator: RoomInfoCoordinator? + private var navigationType: NavigationType = .present + + private enum NavigationType { + case present + case push + } // MARK: Public @@ -61,6 +67,7 @@ final class RoomInfoCoordinatorBridgePresenter: NSObject { roomInfoCoordinator.start() self.coordinator = roomInfoCoordinator + self.navigationType = .present } func push(from navigationController: UINavigationController, animated: Bool) { @@ -71,13 +78,27 @@ final class RoomInfoCoordinatorBridgePresenter: NSObject { roomInfoCoordinator.start() self.coordinator = roomInfoCoordinator + self.navigationType = .push } func dismiss(animated: Bool, completion: (() -> Void)?) { guard let coordinator = self.coordinator else { return } - coordinator.toPresentable().dismiss(animated: animated) { + switch navigationType { + case .present: + coordinator.toPresentable().dismiss(animated: animated) { + self.coordinator = nil + + if let completion = completion { + completion() + } + } + case .push: + guard let navigationController = coordinator.toPresentable() as? UINavigationController else { + return + } + navigationController.popViewController(animated: animated) self.coordinator = nil if let completion = completion { diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 5f8371e6f..93e103e94 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -4548,11 +4548,20 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Note: we check if `currentEventIdAtTableBottom` is set to know whether the table has been rendered at least once. if (!self.roomDataSource.isLive || (currentEventIdAtTableBottom && [self isBubblesTableScrollViewAtTheBottom] == NO)) { - // Retrieve the unread messages count - NSUInteger unreadCount = self.roomDataSource.room.summary.localUnreadEventCount; - - self.scrollToBottomBadgeLabel.text = unreadCount ? [NSString stringWithFormat:@"%lu", unreadCount] : nil; - self.scrollToBottomHidden = NO; + if (self.roomDataSource.room) + { + // Retrieve the unread messages count + NSUInteger unreadCount = self.roomDataSource.room.summary.localUnreadEventCount; + + self.scrollToBottomBadgeLabel.text = unreadCount ? [NSString stringWithFormat:@"%lu", unreadCount] : nil; + self.scrollToBottomHidden = NO; + } + else + { + // will be here for left rooms + self.scrollToBottomBadgeLabel.text = nil; + self.scrollToBottomHidden = YES; + } } else if (serverNotices.usageLimit && serverNotices.usageLimit.isServerNoticeUsageLimit) { diff --git a/RiotTests/EmojiServiceTests.swift b/RiotTests/EmojiServiceTests.swift index b4f6971af..0b4e715cd 100644 --- a/RiotTests/EmojiServiceTests.swift +++ b/RiotTests/EmojiServiceTests.swift @@ -22,7 +22,7 @@ class EmojiServiceTests: XCTestCase { // MARK: - Constants - private let defaultTimeout: TimeInterval = 1.5 + private let defaultTimeout: TimeInterval = 10 enum ExpectedEmojiCategory: Int { case people