-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement tab bar remote message (#3665)
Task/Issue URL: https://app.asana.com/0/1204006570077678/1208970712110808/f Tech Design URL: CC: **Description** Adds a new remote message that is shown in the tab bar. **Steps to test this PR**: 1. Go to the `RemoteMessagingClient` and change the DEBUG endpoint URL to `https://www.jsonblob.com/api/1316017217598578688` 2. Run the app 3. You should see the new blue button in the tab bar 4. When hovering it, it should show a popup. 5. Tapping the button will take you to the survey 6. Test that when the button is dismissed is removed in all windows 7. Test that New Tab Page does not show this new message **Definition of Done**: * [x] Does this PR satisfy our [Definition of Done](https://app.asana.com/0/1202500774821704/1207634633537039/f)? — ###### Internal references: [Pull Request Review Checklist](https://app.asana.com/0/1202500774821704/1203764234894239/f) [Software Engineering Expectations](https://app.asana.com/0/59792373528535/199064865822552) [Technical Design Template](https://app.asana.com/0/59792373528535/184709971311943) [Pull Request Documentation](https://app.asana.com/0/1202500774821704/1204012835277482/f) --------- Co-authored-by: Dominik Kapusta <[email protected]>
- Loading branch information
1 parent
4c48e64
commit 5473b36
Showing
19 changed files
with
817 additions
and
39 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
12 changes: 12 additions & 0 deletions
12
DuckDuckGo/Assets.xcassets/Images/dax-response.imageset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"images" : [ | ||
{ | ||
"filename" : "Response-DDG-Question-96x96.svg", | ||
"idiom" : "universal" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...Go/Assets.xcassets/Images/dax-response.imageset/Response-DDG-Question-96x96.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
DuckDuckGo/RemoteMessaging/TabBarActiveRemoteMessage.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// | ||
// TabBarActiveRemoteMessage.swift | ||
// | ||
// Copyright © 2024 DuckDuckGo. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
import Combine | ||
import RemoteMessaging | ||
|
||
protocol TabBarRemoteMessageProviding { | ||
var remoteMessagePublisher: AnyPublisher<RemoteMessageModel?, Never> { get } | ||
|
||
func markRemoteMessageAsShown() async | ||
func onSurveyOpened() async | ||
func onMessageDismissed() async | ||
} | ||
|
||
final class TabBarActiveRemoteMessage: TabBarRemoteMessageProviding { | ||
private let activeRemoteMessageModel: ActiveRemoteMessageModel | ||
|
||
var remoteMessagePublisher: AnyPublisher<RemoteMessageModel?, Never> { | ||
activeRemoteMessageModel.$tabBarRemoteMessage.eraseToAnyPublisher() | ||
} | ||
|
||
init(activeRemoteMessageModel: ActiveRemoteMessageModel) { | ||
self.activeRemoteMessageModel = activeRemoteMessageModel | ||
} | ||
|
||
func markRemoteMessageAsShown() async { | ||
await activeRemoteMessageModel.markRemoteMessageAsShown() | ||
} | ||
|
||
func onSurveyOpened() async { | ||
await activeRemoteMessageModel.dismissRemoteMessage(with: .primaryAction) | ||
} | ||
|
||
func onMessageDismissed() async { | ||
await activeRemoteMessageModel.dismissRemoteMessage(with: .close) | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
DuckDuckGo/RemoteMessaging/TabBarRemoteMessageView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// | ||
// TabBarRemoteMessageView.swift | ||
// | ||
// Copyright © 2024 DuckDuckGo. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct TabBarRemoteMessageView: View { | ||
@State private var wasViewHovered: Bool = false | ||
@State private var wasCloseButtonHovered: Bool = false | ||
|
||
let model: TabBarRemoteMessage | ||
|
||
let onClose: () -> Void | ||
let onTap: (URL) -> Void | ||
let onHover: () -> Void | ||
let onHoverEnd: () -> Void | ||
let onAppear: () -> Void | ||
|
||
var body: some View { | ||
HStack(spacing: 0) { | ||
HStack { | ||
Text(model.buttonTitle) | ||
.font(.system(size: 13)) | ||
.fixedSize(horizontal: true, vertical: false) | ||
.foregroundColor(.white) | ||
} | ||
.padding([.leading, .top, .bottom], 8) | ||
.padding(.trailing, 6) | ||
.cornerRadius(8) | ||
.background(wasViewHovered | ||
? Color("PrimaryButtonHover") | ||
: Color("PrimaryButtonRest")) | ||
.onTapGesture { onTap(model.surveyURL) } | ||
.onHover { hovering in | ||
wasViewHovered = hovering | ||
|
||
if hovering { | ||
onHover() | ||
} else { | ||
onHoverEnd() | ||
} | ||
} | ||
|
||
Divider() | ||
.background(Color.white.opacity(0.3)) | ||
.frame(width: 1) | ||
.padding([.top, .bottom], 3) | ||
|
||
HStack { | ||
Image(.close) | ||
.resizable() | ||
.scaledToFit() | ||
.foregroundColor(.white) | ||
.frame(width: 16, height: 16) | ||
} | ||
.padding([.top, .bottom]) | ||
.padding([.leading, .trailing], 4) | ||
.background(wasCloseButtonHovered | ||
? Color("PrimaryButtonHover") | ||
: Color("PrimaryButtonRest")) | ||
.cornerRadius(8) | ||
.onTapGesture { | ||
onClose() | ||
} | ||
.onHover { hovering in | ||
wasCloseButtonHovered = hovering | ||
} | ||
.frame(maxWidth: .infinity) | ||
} | ||
.background(wasCloseButtonHovered || wasViewHovered | ||
? Color("PrimaryButtonHover") | ||
: Color("PrimaryButtonRest")) | ||
.frame(height: 24) | ||
.cornerRadius(8) | ||
.onAppear(perform: { onAppear() }) | ||
} | ||
} | ||
|
||
struct TabBarRemoteMessagePopoverContent: View { | ||
let model: TabBarRemoteMessage | ||
|
||
var body: some View { | ||
HStack(alignment: .center, spacing: 12) { | ||
Image(.daxResponse) | ||
.resizable() | ||
.scaledToFit() | ||
.frame(width: 72, height: 72) | ||
|
||
VStack(alignment: .leading, spacing: 8) { | ||
Text(model.popupTitle) | ||
.font(.system(size: 13, weight: .bold)) | ||
.padding(.top, 9) | ||
|
||
Text(model.popupSubtitle) | ||
.font(.system(size: 13, weight: .medium)) | ||
.padding(.bottom, 9) | ||
} | ||
} | ||
.frame(width: 360) | ||
.padding([.top, .bottom], 10) | ||
.padding(.leading, 12) | ||
.padding(.trailing, 24) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// TabBarRemoteMessage.swift | ||
// | ||
// Copyright © 2024 DuckDuckGo. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
struct TabBarRemoteMessage { | ||
static let tabBarPermanentSurveyRemoteMessageId = "macos_permanent_survey_tab_bar" | ||
|
||
let buttonTitle: String | ||
let popupTitle: String | ||
let popupSubtitle: String | ||
let surveyURL: URL | ||
} |
Oops, something went wrong.