Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOS-2456 Membership | Use features from API #1096

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 30 additions & 24 deletions Anytype/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1458,28 +1458,10 @@ internal enum Loc {
internal static let title4 = Loc.tr("Localizable", "Membership.Banner.Title4", fallback: "Invest in Connectivity")
}
internal enum Builder {
/// Unique name (from 7 characters)
internal static let benefit1 = Loc.tr("Localizable", "Membership.Builder.Benefit1", fallback: "Unique name (from 7 characters)")
/// 128 GB of network space
internal static let benefit2 = Loc.tr("Localizable", "Membership.Builder.Benefit2", fallback: "128 GB of network space")
/// 10 Guest collaborator seats
internal static let benefit3 = Loc.tr("Localizable", "Membership.Builder.Benefit3", fallback: "10 Guest collaborator seats")
/// Priority support
internal static let benefit4 = Loc.tr("Localizable", "Membership.Builder.Benefit4", fallback: "Priority support")
/// Unlock the magic of multi-party collaboration and enjoy top-notch support
internal static let subtitle = Loc.tr("Localizable", "Membership.Builder.Subtitle", fallback: "Unlock the magic of multi-party collaboration and enjoy top-notch support")
}
internal enum CoCreator {
/// Unique name (from 5 characters)
internal static let benefit1 = Loc.tr("Localizable", "Membership.CoCreator.Benefit1", fallback: "Unique name (from 5 characters)")
/// 256 GB of network space
internal static let benefit2 = Loc.tr("Localizable", "Membership.CoCreator.Benefit2", fallback: "256 GB of network space")
/// 25 Guest collaborator seats
internal static let benefit3 = Loc.tr("Localizable", "Membership.CoCreator.Benefit3", fallback: "25 Guest collaborator seats")
/// Chat with the team
internal static let benefit4 = Loc.tr("Localizable", "Membership.CoCreator.Benefit4", fallback: "Chat with the team")
/// Unique collectible
internal static let benefit5 = Loc.tr("Localizable", "Membership.CoCreator.Benefit5", fallback: "Unique collectible")
/// Support our adventure and unlock exclusive access and perks
internal static let subtitle = Loc.tr("Localizable", "Membership.CoCreator.Subtitle", fallback: "Support our adventure and unlock exclusive access and perks")
}
Expand Down Expand Up @@ -1511,15 +1493,39 @@ internal enum Loc {
internal static let title = Loc.tr("Localizable", "Membership.EmailForm.Title", fallback: "Get your free membership")
}
internal enum Explorer {
/// 1 GB of network space
internal static let benefit1 = Loc.tr("Localizable", "Membership.Explorer.Benefit1", fallback: "1 GB of network space")
/// 10 one-to-one spaces
internal static let benefit2 = Loc.tr("Localizable", "Membership.Explorer.Benefit2", fallback: "10 one-to-one spaces")
/// Up to 10 shared spaces in read-only mode
internal static let benefit3 = Loc.tr("Localizable", "Membership.Explorer.Benefit3", fallback: "Up to 10 shared spaces in read-only mode")
/// Dive into the network and enjoy the thrill of one-on-one collaboration
internal static let subtitle = Loc.tr("Localizable", "Membership.Explorer.Subtitle", fallback: "Dive into the network and enjoy the thrill of one-on-one collaboration")
}
internal enum Feature {
/// %@ Invitations
internal static func invites(_ p1: Any) -> String {
return Loc.tr("Localizable", "Membership.Feature.Invites", String(describing: p1), fallback: "%@ Invitations")
}
/// Local, non-unique name
internal static let localName = Loc.tr("Localizable", "Membership.Feature.LocalName", fallback: "Local, non-unique name")
/// %@ Shared spaces
internal static func sharedSpaces(_ p1: Any) -> String {
return Loc.tr("Localizable", "Membership.Feature.SharedSpaces", String(describing: p1), fallback: "%@ Shared spaces")
}
/// %@ Editors per space
internal static func spaceWriters(_ p1: Any) -> String {
return Loc.tr("Localizable", "Membership.Feature.SpaceWriters", String(describing: p1), fallback: "%@ Editors per space")
}
/// %@ GB of backup & sync space
internal static func storageGB(_ p1: Any) -> String {
return Loc.tr("Localizable", "Membership.Feature.StorageGB", String(describing: p1), fallback: "%@ GB of backup & sync space")
}
/// Unique Network name (%@+ characters)
internal static func uniqueName(_ p1: Any) -> String {
return Loc.tr("Localizable", "Membership.Feature.UniqueName", String(describing: p1), fallback: "Unique Network name (%@+ characters)")
}
/// Unlimited Viewers for shared spaces
internal static let unlimitedViewers = Loc.tr("Localizable", "Membership.Feature.UnlimitedViewers", fallback: "Unlimited Viewers for shared spaces")
/// %@ Viewers for shared spaces
internal static func viewers(_ p1: Any) -> String {
return Loc.tr("Localizable", "Membership.Feature.Viewers", String(describing: p1), fallback: "%@ Viewers for shared spaces")
}
}
internal enum Legal {
/// Membership levels details
internal static let details = Loc.tr("Localizable", "Membership.Legal.Details", fallback: "Membership levels details")
Expand Down
24 changes: 8 additions & 16 deletions Anytype/Resources/Strings/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1106,27 +1106,19 @@
"Membership.Payment.Google subscription" = "Google subscription";


// MARK: - Membership Tiers
"Membership.Explorer.Subtitle" = "Dive into the network and enjoy the thrill of one-on-one collaboration";
"Membership.Explorer.Benefit1" = "1 GB of network space";
"Membership.Explorer.Benefit2" = "10 one-to-one spaces";
"Membership.Explorer.Benefit3" = "Up to 10 shared spaces in read-only mode";

"Membership.Builder.Subtitle" = "Unlock the magic of multi-party collaboration and enjoy top-notch support";
"Membership.Builder.Benefit1" = "Unique name (from 7 characters)";
"Membership.Builder.Benefit2" = "128 GB of network space";
"Membership.Builder.Benefit3" = "10 Guest collaborator seats";
"Membership.Builder.Benefit4" = "Priority support";

"Membership.CoCreator.Subtitle" = "Support our adventure and unlock exclusive access and perks";
"Membership.CoCreator.Benefit1" = "Unique name (from 5 characters)";
"Membership.CoCreator.Benefit2" = "256 GB of network space";
"Membership.CoCreator.Benefit3" = "25 Guest collaborator seats";
"Membership.CoCreator.Benefit4" = "Chat with the team";
"Membership.CoCreator.Benefit5" = "Unique collectible";

"Membership.Custom.Subtitle" = "Membership tailored to your specific needs and preferences";

"Membership.Feature.LocalName" = "Local, non-unique name";
"Membership.Feature.UniqueName" = "Unique Network name (%@+ characters)";
"Membership.Feature.StorageGB" = "%@ GB of backup & sync space";
"Membership.Feature.Invites" = "%@ Invitations";
"Membership.Feature.SpaceWriters" = "%@ Editors per space";
"Membership.Feature.UnlimitedViewers" = "Unlimited Viewers for shared spaces";
"Membership.Feature.Viewers" = "%@ Viewers for shared spaces";
"Membership.Feature.SharedSpaces" = "%@ Shared spaces";

// MARK: - Debug
"Debug.MimeTypes" = "Mime Types - %@";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,6 @@ extension MembershipTier {
}
}

var benefits: [String] {
switch self.type {
case .explorer:
[
Loc.Membership.Explorer.benefit1,
Loc.Membership.Explorer.benefit2,
Loc.Membership.Explorer.benefit3
]
case .builder:
[
Loc.Membership.Builder.benefit1,
Loc.Membership.Builder.benefit2,
Loc.Membership.Builder.benefit3,
Loc.Membership.Builder.benefit4
]
case .coCreator:
[
Loc.Membership.CoCreator.benefit1,
Loc.Membership.CoCreator.benefit2,
Loc.Membership.CoCreator.benefit3,
Loc.Membership.CoCreator.benefit4,
Loc.Membership.CoCreator.benefit5
]
case .custom:
[
// TBD in future updates
]
}
}

var mediumIcon: ImageAsset {
switch self.type {
case .explorer:
Expand Down Expand Up @@ -86,23 +56,107 @@ extension MembershipTier {
.purple
}
}

var featureDescriptions: [String] {
var featureDescriptions = [anyName.description]
featureDescriptions.append(contentsOf: features.map(\.description))
return featureDescriptions
}
}

extension MembershipAnyName {
var description: String {
switch self {
case .none:
Loc.Membership.Feature.localName
case .some(let minLenght):
Loc.Membership.Feature.uniqueName(minLenght)
}
}
}

extension MembershipFeature {
var description: String {
switch self {
case .storageGbs(let value):
Loc.Membership.Feature.storageGB(value)
case .invites(let value):
Loc.Membership.Feature.invites(value)
case .spaceWriters(let value):
Loc.Membership.Feature.spaceWriters(value)
case .spaceReaders(let value):
switch value {
case .int(let intValue):
if intValue == 1024 { // Middleware understanding of Unlimited
Loc.Membership.Feature.unlimitedViewers
} else {
Loc.Membership.Feature.viewers(intValue)
}
case .string(let stringValue):
Loc.Membership.Feature.viewers(stringValue)
}
case .sharedSpaces(let value):
Loc.Membership.Feature.sharedSpaces(value)
}
}
}


// MARK: - Mocks
extension MembershipTier {
static var mockExplorer: MembershipTier {
MembershipTier(type: .explorer, name: "Explorer", anyName: .none)
MembershipTier(
type: .explorer,
name: "Explorer",
anyName: .none,
features: [
.storageGbs(.int(1)),
.sharedSpaces(.int(3)),
.spaceWriters(.int(3)),
.spaceReaders(.int(3))
]
)
}

static var mockBuilder: MembershipTier {
MembershipTier(type: .builder, name: "Builder", anyName: .some(minLenght: 7))
MembershipTier(
type: .builder,
name: "Builder",
anyName: .some(minLenght: 7),
features: [
.storageGbs(.int(128)),
.sharedSpaces(.int(3)),
.spaceWriters(.int(10)),
.spaceReaders(.int(1024))
]
)
}

static var mockCoCreator: MembershipTier {
MembershipTier(type: .coCreator, name: "CockCreator", anyName: .some(minLenght: 5))
MembershipTier(
type: .coCreator,
name: "CockCreator",
anyName: .some(minLenght: 5),
features: [
.storageGbs(.int(256)),
.sharedSpaces(.int(3)),
.spaceWriters(.int(10)),
.spaceReaders(.int(1024))
]
)
}

static var mockCustom: MembershipTier {
MembershipTier(type: .custom(id: 228), name: "Na-Baron", anyName: .some(minLenght: 3))
MembershipTier(
type: .custom(id: 228),
name: "Na-Baron",
anyName: .some(minLenght: 3),
features: [
.storageGbs(.int(2560)),
.sharedSpaces(.int(333)),
.spaceWriters(.int(100)),
.spaceReaders(.int(1024)),
]
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ struct MembershipTierInfoView: View {
VStack(alignment: .leading, spacing: 0) {
AnytypeText(Loc.whatSIncluded, style: .calloutRegular, color: .Text.secondary)
Spacer.fixedHeight(6)
ForEach(tier.benefits, id: \.self) { benefit in
ForEach(tier.featureDescriptions, id: \.self) { feature in
HStack(spacing: 8) {
Image(asset: .System.textCheckMark)
.frame(width: 16, height: 16)
.foregroundColor(.Text.primary)
AnytypeText(benefit, style: .calloutRegular, color: .Text.primary)
AnytypeText(feature, style: .calloutRegular, color: .Text.primary)
.lineLimit(1)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,46 @@ public enum MembershipAnyName: Hashable, Equatable {
case some(minLenght: UInt32)
}

public enum MembershipFeature: Hashable, Equatable {
public enum Value: Hashable, Equatable, CustomStringConvertible {
case int(UInt32)
case string(String)

public var description: String {
switch self {
case .int(let int):
String(describing: int)
case .string(let string):
string
}
}
}

case storageGbs(Value)
case invites(Value)
case spaceWriters(Value)
case spaceReaders(Value)
case sharedSpaces(Value)
}

public struct MembershipTier: Hashable, Identifiable, Equatable {
public let type: MembershipTierType
public let name: String
public let anyName: MembershipAnyName
public let features: [MembershipFeature]

public var id: MembershipTierType { type }

public init(
type: MembershipTierType,
name: String,
anyName: MembershipAnyName
anyName: MembershipAnyName,
features: [MembershipFeature]
) {
self.type = type
self.name = name
self.anyName = anyName
self.features = features
}
}

Expand All @@ -71,12 +96,40 @@ extension Anytype_Model_MembershipTierData {
func asModel() -> MembershipTier? {
guard let type = MembershipTierType(intId: id) else { return nil }

let anyName: MembershipAnyName = anyNamesCountIncluded > 0 ? .some(minLenght: anyNamesCountIncluded) : .none
let anyName: MembershipAnyName = anyNamesCountIncluded > 0 ? .some(minLenght: anyNameMinLength) : .none

return MembershipTier(
type: type,
name: name,
anyName: anyName
anyName: anyName,
features: getFeatures()
)
}

func getFeatures() -> [MembershipFeature] {
features.compactMap { feature in
switch feature.featureID {
case .storageGbs:
return .storageGbs(extractFeatureValue(feature: feature))
case .invites:
return .invites(extractFeatureValue(feature: feature))
case .spaceWriters:
return .spaceWriters(extractFeatureValue(feature: feature))
case .spaceReaders:
return .spaceReaders(extractFeatureValue(feature: feature))
case .sharedSpaces:
return .sharedSpaces(extractFeatureValue(feature: feature))
case .UNRECOGNIZED, .unknown:
return nil
}
}
}

private func extractFeatureValue(feature: Feature) -> MembershipFeature.Value {
if feature.valueUint > 0 {
return .int(feature.valueUint)
}

return .string(feature.valueStr)
}
}
Loading