-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1513 from planetary-social/content-flag-category
Content flag category selection
- Loading branch information
Showing
6 changed files
with
274 additions
and
4 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import SwiftUI | ||
/// Displays a list of selectable flag options | ||
struct FlagOptionPicker: View { | ||
@Binding private var selectedOption: FlagOption? | ||
var options: [FlagOption] | ||
var title: String | ||
var subtitle: String? | ||
|
||
init(selectedOption: Binding<FlagOption?>, options: [FlagOption], title: String, subtitle: String?) { | ||
self._selectedOption = selectedOption | ||
self.options = options | ||
self.title = title | ||
self.subtitle = subtitle | ||
} | ||
|
||
var body: some View { | ||
VStack(alignment: .leading) { | ||
HeaderView(text: title) | ||
|
||
if let subtitle = subtitle { | ||
HeaderView(text: subtitle) | ||
} | ||
flagOptionsListView | ||
} | ||
.padding() | ||
} | ||
|
||
private var flagOptionsListView: some View { | ||
VStack(alignment: .leading, spacing: 0) { | ||
ForEach(options) { flag in | ||
FlagPickerRow(flag: flag, selection: $selectedOption) | ||
BeveledSeparator() | ||
} | ||
} | ||
.background(LinearGradient.cardBackground) | ||
.clipShape(RoundedRectangle(cornerRadius: 15)) | ||
} | ||
} | ||
|
||
/// A single row for a single flag option | ||
struct FlagPickerRow: View { | ||
var flag: FlagOption | ||
@Binding var selection: FlagOption? | ||
|
||
var isSelected: Bool { | ||
selection?.id == flag.id | ||
} | ||
|
||
var body: some View { | ||
Button(action: { | ||
selection = flag | ||
}, label: { | ||
buttonLabel | ||
}) | ||
.padding(14) | ||
} | ||
|
||
private var buttonLabel: some View { | ||
HStack(alignment: .center) { | ||
VStack(alignment: .leading, spacing: 8) { | ||
Text(flag.title) | ||
.foregroundColor(.primaryTxt) | ||
.font(.clarity(.regular)) | ||
|
||
if let description = flag.description { | ||
Text(description) | ||
.foregroundColor(.secondaryTxt) | ||
.multilineTextAlignment(.leading) | ||
.font(.clarity(.regular, textStyle: .footnote)) | ||
.lineSpacing(8) | ||
} | ||
} | ||
Spacer() | ||
|
||
NosRadioButton(isSelected: isSelected) | ||
} | ||
} | ||
} | ||
|
||
private struct HeaderView: View { | ||
var text: String | ||
var body: some View { | ||
Text(text) | ||
.lineSpacing(5) | ||
.foregroundColor(.primaryTxt) | ||
.font(.clarity(.bold)) | ||
.padding(.bottom, 28) | ||
} | ||
} | ||
|
||
#Preview { | ||
struct PreviewWrapper: View { | ||
@State private var selectedFlag: FlagOption? | ||
|
||
var body: some View { | ||
FlagOptionPicker( | ||
selectedOption: $selectedFlag, | ||
options: FlagOption.flagContentCategories, | ||
title: "Create a tag for this content that other people in your network can see.", | ||
subtitle: "Select a tag for the content" | ||
) | ||
.onAppear { | ||
selectedFlag = FlagOption.flagContentCategories.first | ||
} | ||
.background(Color.appBg) | ||
} | ||
} | ||
return PreviewWrapper() | ||
} |
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,65 @@ | ||
import SwiftUI | ||
/// A custom radio button. | ||
struct NosRadioButton: View { | ||
var isSelected: Bool | ||
var body: some View { | ||
ZStack { | ||
RadioButtonBackground() | ||
if isSelected { | ||
RadioButtonSelectedIndicator() | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// A custom background for a radio button. | ||
private struct RadioButtonBackground: View { | ||
var body: some View { | ||
ZStack { | ||
Circle() | ||
.fill( | ||
LinearGradient( | ||
colors: [Color.radioButtonBgTop, Color.radioButtonBgBottom], | ||
startPoint: .top, | ||
endPoint: .bottom | ||
) | ||
) | ||
.frame(width: 25, height: 25) | ||
// Inner shadow effect | ||
.overlay( | ||
Circle() | ||
.fill( | ||
LinearGradient( | ||
colors: [Color.radioButtonBgTop, Color.radioButtonBgBottom], | ||
startPoint: .top, | ||
endPoint: .bottom | ||
) | ||
) | ||
.stroke(Color.radioButtonInnerDropShadow, lineWidth: 1) | ||
.blur(radius: 1.67) | ||
.offset(x: 0, y: 0.67) | ||
.mask(Circle()) // Ensures the inner shadow stays within the circle's shape | ||
) | ||
|
||
// Outer shadow effect | ||
.shadow(color: Color.radioButtonOuterDropShadow, radius: 0, x: 0, y: 0.99) | ||
} | ||
} | ||
} | ||
|
||
/// A colorful selector (inner circle) of a radio button with a gradient fill. | ||
private struct RadioButtonSelectedIndicator: View { | ||
var body: some View { | ||
Circle() | ||
.fill(LinearGradient.verticalAccentPrimary) | ||
.frame(width: 17, height: 17) | ||
} | ||
} | ||
|
||
#Preview("Selected") { | ||
NosRadioButton(isSelected: true) | ||
} | ||
|
||
#Preview("Not Selected") { | ||
NosRadioButton(isSelected: false) | ||
} |
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,25 @@ | ||
import SwiftUI | ||
|
||
/// Displays pickers for selecting content flag option category, with additional stages shown | ||
/// based on previous selections. | ||
struct ContentFlagView: View { | ||
@Binding var selectedFlagOptionCategory: FlagOption? | ||
|
||
var body: some View { | ||
ScrollView { | ||
VStack { | ||
FlagOptionPicker( | ||
selectedOption: $selectedFlagOptionCategory, | ||
options: FlagOption.flagContentCategories, | ||
title: String(localized: .localizable.flagContentCategoryTitle), | ||
subtitle: String(localized: .localizable.flagContentCategoryDescription) | ||
) | ||
} | ||
} | ||
.background(Color.appBg) | ||
} | ||
} | ||
|
||
#Preview { | ||
ContentFlagView(selectedFlagOptionCategory: .constant(nil)) | ||
} |
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