- Implemented theme colors.
- Implemented the content length options.
- Implemented the font size options.
- Implemented the compact / comfortable options.
- Improved the logic for the rounded corners on cards.
This commit is contained in:
David Sinclair 2023-03-02 15:31:21 -07:00
parent 2b10b82c75
commit aa88601905
5 changed files with 168 additions and 50 deletions

View file

@ -17,10 +17,9 @@ struct CardView: View {
var body: some View {
ZStack(alignment: .leading) {
if story.isSelected || cache.isGrid {
RoundedRectangle(cornerRadius: 10).foregroundColor(.init(white: 0.9))
RoundedRectangle(cornerRadius: 10).foregroundColor(highlightColor)
CardFeedBarView(cache: cache, story: story)
.clipShape(RoundedRectangle(cornerRadius: 10))
.padding(.leading, 2)
} else {
CardFeedBarView(cache: cache, story: story)
@ -39,15 +38,16 @@ struct CardView: View {
}
HStack {
if !cache.isGrid, cache.settings.listPreview.isLeft, let previewImage {
if !cache.isGrid, cache.settings.preview.isLeft, let previewImage {
listPreview(image: previewImage)
}
CardContentView(cache: cache, story: story)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
.padding(15)
.padding([.leading, .trailing], 15)
.padding([.top, .bottom], cache.settings.spacing == .compact ? 10 : 15)
if !cache.isGrid, !cache.settings.listPreview.isLeft, let previewImage {
if !cache.isGrid, !cache.settings.preview.isLeft, let previewImage {
listPreview(image: previewImage)
// Image(uiImage: previewImage)
@ -60,6 +60,9 @@ struct CardView: View {
}
}
}
.if(cache.isGrid || story.isSelected) { view in
view.clipShape(RoundedRectangle(cornerRadius: 10))
}
.if(story.isSelected) { view in
view.padding(10)
}
@ -130,8 +133,16 @@ struct CardView: View {
// }
// }
var highlightColor: Color {
if cache.isGrid {
return Color.themed([0xFDFCFA, 0xFFFDEF, 0x4F4F4F, 0x292B2C])
} else {
return Color.themed([0xFFFDEF, 0xEEECCD, 0x303A40, 0x303030])
}
}
var previewImage: UIImage? {
guard cache.settings.listPreview != .none, let image = cache.appDelegate.cachedImage(forStoryHash: story.hash), image.isKind(of: UIImage.self) else {
guard cache.settings.preview != .none, let image = cache.appDelegate.cachedImage(forStoryHash: story.hash), image.isKind(of: UIImage.self) else {
return nil
}
@ -151,9 +162,9 @@ struct CardView: View {
@ViewBuilder
func listPreview(image: UIImage) -> some View {
let isLeft = cache.settings.listPreview.isLeft
let isLeft = cache.settings.preview.isLeft
if cache.settings.listPreview.isSmall {
if cache.settings.preview.isSmall {
Image(uiImage: image)
.resizable()
.scaledToFill()
@ -167,7 +178,7 @@ struct CardView: View {
.resizable()
.scaledToFill()
.frame(width: 90)
.cornerRadius(10, corners: isLeft || !story.isSelected ? [] : [.topRight, .bottomRight])
.clipped()
.padding(.leading, isLeft ? 8 : -10)
.padding(.trailing, isLeft ? -10 : 0)
}
@ -208,8 +219,9 @@ struct CardContentView: View {
.padding(.leading, 24)
Text(story.feedName)
.font(.custom("WhitneySSm-Medium", size: 10, relativeTo: .caption))
.font(font(named: "WhitneySSm-Medium", size: 10))
.lineLimit(1)
.foregroundColor(feedColor)
}
}
@ -238,14 +250,28 @@ struct CardContentView: View {
}
Text(story.title)
.font(.custom("WhitneySSm-Medium", size: 18, relativeTo: .caption).bold())
.font(font(named: "WhitneySSm-Medium", size: 18).bold())
.foregroundColor(titleColor)
.lineLimit(cache.isGrid ? StorySettings.Content.titleLimit : cache.settings.content.limit)
.truncationMode(.tail)
}
Text(story.content.prefix(400))
.font(.custom("WhitneySSm-Book", size: 13, relativeTo: .caption))
.padding(.top, 5)
.padding(.bottom, cache.settings.spacing == .compact ? -5 : 0)
if cache.isGrid || cache.settings.content != .title {
Text(story.content)
.font(font(named: "WhitneySSm-Book", size: 13))
.foregroundColor(contentColor)
.lineLimit(cache.isGrid ? StorySettings.Content.contentLimit : cache.settings.content.limit)
.truncationMode(.tail)
.padding(.top, 5)
.padding(.bottom, cache.settings.spacing == .compact ? -5 : 0)
}
Spacer()
Text(story.dateAndAuthor)
.font(.custom("WhitneySSm-Medium", size: 10, relativeTo: .caption))
.font(font(named: "WhitneySSm-Medium", size: 10))
.foregroundColor(dateAndAuthorColor)
.padding(.top, 5)
}
}
@ -270,6 +296,40 @@ struct CardContentView: View {
return UIImage(named: "indicator-unread")
}
}
func font(named: String, size: CGFloat) -> Font {
return Font.custom(named, size: size + cache.settings.fontSize.offset, relativeTo: .caption)
}
var feedColor: Color {
return contentColor
}
var titleColor: Color {
if story.isSelected {
return Color.themed([0x686868, 0xA0A0A0])
} else if story.isRead {
return Color.themed([0x585858, 0x585858, 0x989898, 0x888888])
} else {
return Color.themed([0x111111, 0x333333, 0xD0D0D0, 0xCCCCCC])
}
}
var contentColor: Color {
if story.isSelected, story.isRead {
return Color.themed([0xB8B8B8, 0xB8B8B8, 0xA0A0A0, 0x707070])
} else if story.isSelected {
return Color.themed([0x888785, 0x686868, 0xA9A9A9, 0x989898])
} else if story.isRead {
return Color.themed([0xB8B8B8, 0xB8B8B8, 0xA0A0A0, 0x707070])
} else {
return Color.themed([0x404040, 0x404040, 0xC0C0C0, 0xB0B0B0])
}
}
var dateAndAuthorColor: Color {
return contentColor
}
}
struct CardFeedBarView: View {

View file

@ -71,6 +71,7 @@ struct FeedDetailGridView: View {
view.padding()
}
}
.background(Color.themed([0xF4F4F4, 0xFFFDEF, 0x4F4F4F, 0x101010]))
}
@ViewBuilder

View file

@ -19,7 +19,7 @@ struct StoryView: View {
var body: some View {
VStack {
ZStack {
Color(white: 0.9)
Color.themed([0xFFFDEF, 0xEEECCD, 0x303A40, 0x303030])
HStack {
Text(story.title)
@ -36,7 +36,7 @@ struct StoryView: View {
}
}
.font(.custom("WhitneySSm-Medium", size: 14, relativeTo: .body))
.foregroundColor(.secondary)
.foregroundColor(Color.themed([0x686868, 0xA0A0A0]))
.frame(height: 50)
.clipShape(RoundedRectangle(cornerRadius: 10))
.onTapGesture {
@ -48,7 +48,7 @@ struct StoryView: View {
}
var previewImage: UIImage? {
guard cache.settings.listPreview != .none, let image = cache.appDelegate.cachedImage(forStoryHash: story.hash), image.isKind(of: UIImage.self) else {
guard cache.settings.preview != .none, let image = cache.appDelegate.cachedImage(forStoryHash: story.hash), image.isKind(of: UIImage.self) else {
return nil
}

View file

@ -24,6 +24,7 @@ class Story: Identifiable {
var content = ""
var dateString = ""
var timestamp = 0
var isRead = false
var isSaved = false
var isShared = false
var score = 0
@ -99,6 +100,7 @@ class Story: Identifiable {
score = Int(NewsBlurAppDelegate.computeStoryScore(intelligence))
}
isRead = score < 0
isRiverOrSocial = storiesCollection.isRiverOrSocial
}
@ -107,9 +109,9 @@ class Story: Identifiable {
let scanner = Scanner(string: hex)
var color: Int64 = 0
scanner.scanHexInt64(&color)
let array = [NSNumber(value: color)]
let value = Int(color)
return ThemeManager.color(fromRGB: array)
return ThemeManager.shared.fixedColor(fromRGB: value) ?? UIColor.gray
}
}
@ -149,19 +151,44 @@ class StoryCache: ObservableObject {
class StorySettings {
let defaults = UserDefaults.standard
//TODO: 🚧
// var listContent: Int {
// NSString *preferenceKey = @"story_list_preview_text_size";
// NSArray *titles = @[@"Title", @"content_preview_small.png", @"content_preview_medium.png", @"content_preview_large.png"];
// NSArray *values = @[@"title", @"short", @"medium", @"long"];
// }
enum Content: String, RawRepresentable {
case title
case short
case medium
case long
static let titleLimit = 6
static let contentLimit = 10
var limit: Int {
switch self {
case .title:
return 6
case .short:
return 2
case .medium:
return 4
case .long:
return 6
}
}
}
enum ListPreview {
var content: Content {
if let string = defaults.string(forKey: "story_list_preview_text_size"), let value = Content(rawValue: string) {
return value
} else {
return .short
}
}
enum Preview: String, RawRepresentable {
case none
case smallLeft
case largeLeft
case largeRight
case smallRight
case smallLeft = "small_left"
case largeLeft = "large_left"
case largeRight = "large_right"
case smallRight = "small_right"
var isLeft: Bool {
return [.smallLeft, .largeLeft].contains(self)
@ -172,31 +199,57 @@ class StorySettings {
}
}
var listPreview: ListPreview {
switch defaults.string(forKey: "story_list_preview_images_size") {
case "none":
return .none
case "small_left":
return .smallLeft
case "large_left":
return .largeLeft
case "large_right":
return .largeRight
default:
var preview: Preview {
if let string = defaults.string(forKey: "story_list_preview_images_size"), let value = Preview(rawValue: string) {
return value
} else {
return .smallRight
}
}
//TODO: 🚧
// NSString *preferenceKey = @"feed_list_font_size";
// NSArray *titles = @[@"XS", @"S", @"M", @"L", @"XL"];
// NSArray *values = @[@"xs", @"small", @"medium", @"large", @"xl"];
enum FontSize: String, RawRepresentable {
case xs
case small
case medium
case large
case xl
var offset: CGFloat {
switch self {
case .xs:
return -2
case .small:
return -1
case .medium:
return 0
case .large:
return 1
case .xl:
return 2
}
}
}
//TODO: 🚧
// preferenceKey = @"feed_list_spacing";
// titles = @[@"Compact", @"Comfortable"];
// values = @[@"compact", @"comfortable"];
var fontSize: FontSize {
if let string = defaults.string(forKey: "feed_list_font_size"), let value = FontSize(rawValue: string) {
return value
} else {
return .medium
}
}
enum Spacing: String, RawRepresentable {
case compact
case comfortable
}
var spacing: Spacing {
if let string = defaults.string(forKey: "feed_list_spacing"), let value = Spacing(rawValue: string) {
return value
} else {
return .comfortable
}
}
// enum GridColumns: String {
// case auto = "auto"

View file

@ -53,4 +53,8 @@ extension Color {
return Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1)
)
}
static func themed(_ hex: [NSNumber]) -> Color {
return Color(ThemeManager.color(fromRGB: hex))
}
}