🚚 💄 Move everything and create episode view cell

pull/1/head
Alexis Drai 2 years ago
parent 3fb273e6dd
commit c1d716ea35

@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
EC37FB2A2A1A3231005C78D6 /* Episode.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC37FB292A1A3231005C78D6 /* Episode.swift */; };
EC37FB2C2A1A3E03005C78D6 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC37FB2B2A1A3E03005C78D6 /* Color.swift */; };
EC37FB322A1A49EB005C78D6 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC37FB312A1A49EB005C78D6 /* Strings.swift */; };
EC8CF6202A13A4F200BE6FD5 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC8CF61F2A13A4F200BE6FD5 /* Colors.xcassets */; };
EC8CF6232A13A59400BE6FD5 /* LibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC8CF6222A13A59400BE6FD5 /* LibraryView.swift */; };
EC8CF6252A13A7F000BE6FD5 /* Podcast.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC8CF6242A13A7F000BE6FD5 /* Podcast.swift */; };
@ -19,6 +22,9 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
EC37FB292A1A3231005C78D6 /* Episode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Episode.swift; sourceTree = "<group>"; };
EC37FB2B2A1A3E03005C78D6 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
EC37FB312A1A49EB005C78D6 /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
EC8CF61F2A13A4F200BE6FD5 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
EC8CF6222A13A59400BE6FD5 /* LibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryView.swift; sourceTree = "<group>"; };
EC8CF6242A13A7F000BE6FD5 /* Podcast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Podcast.swift; sourceTree = "<group>"; };
@ -42,10 +48,27 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
EC37FB2D2A1A3FA4005C78D6 /* Extensions */ = {
isa = PBXGroup;
children = (
EC37FB2B2A1A3E03005C78D6 /* Color.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
EC37FB2E2A1A4941005C78D6 /* Strings */ = {
isa = PBXGroup;
children = (
EC37FB312A1A49EB005C78D6 /* Strings.swift */,
);
path = Strings;
sourceTree = "<group>";
};
EC8CF6212A13A57400BE6FD5 /* Model */ = {
isa = PBXGroup;
children = (
EC8CF6242A13A7F000BE6FD5 /* Podcast.swift */,
EC37FB292A1A3231005C78D6 /* Episode.swift */,
);
path = Model;
sourceTree = "<group>";
@ -70,10 +93,10 @@
isa = PBXGroup;
children = (
EC8CF6212A13A57400BE6FD5 /* Model */,
EC8CF61F2A13A4F200BE6FD5 /* Colors.xcassets */,
ECB23BA42A0E45CC00A1C62B /* Views */,
ECB23BA42A0E45CC00A1C62B /* View */,
ECB23B922A0E33B000A1C62B /* PodcastsCloneApp.swift */,
ECB23B962A0E33B200A1C62B /* Assets.xcassets */,
EC8CF61F2A13A4F200BE6FD5 /* Colors.xcassets */,
ECB23B982A0E33B200A1C62B /* Preview Content */,
);
path = PodcastsClone;
@ -87,15 +110,17 @@
path = "Preview Content";
sourceTree = "<group>";
};
ECB23BA42A0E45CC00A1C62B /* Views */ = {
ECB23BA42A0E45CC00A1C62B /* View */ = {
isa = PBXGroup;
children = (
EC37FB2D2A1A3FA4005C78D6 /* Extensions */,
EC37FB2E2A1A4941005C78D6 /* Strings */,
ECB23BA02A0E3FDF00A1C62B /* MainView.swift */,
ECB23BA22A0E455300A1C62B /* PodcastDetailView.swift */,
ECB23BA52A0E4C0B00A1C62B /* EpisodeViewCell.swift */,
EC8CF6222A13A59400BE6FD5 /* LibraryView.swift */,
);
path = Views;
path = View;
sourceTree = "<group>";
};
/* End PBXGroup section */
@ -170,9 +195,12 @@
buildActionMask = 2147483647;
files = (
ECB23BA12A0E3FDF00A1C62B /* MainView.swift in Sources */,
EC37FB322A1A49EB005C78D6 /* Strings.swift in Sources */,
EC37FB2A2A1A3231005C78D6 /* Episode.swift in Sources */,
ECB23BA62A0E4C0B00A1C62B /* EpisodeViewCell.swift in Sources */,
EC8CF6252A13A7F000BE6FD5 /* Podcast.swift in Sources */,
ECB23BA32A0E455300A1C62B /* PodcastDetailView.swift in Sources */,
EC37FB2C2A1A3E03005C78D6 /* Color.swift in Sources */,
EC8CF6232A13A59400BE6FD5 /* LibraryView.swift in Sources */,
ECB23B932A0E33B000A1C62B /* PodcastsCloneApp.swift in Sources */,
);

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.871",
"green" : "0.314",
"red" : "0.490"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.871",
"green" : "0.314",
"red" : "0.490"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.980",
"green" : "0.980",
"red" : "0.980"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.020",
"green" : "0.020",
"red" : "0.020"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.900",
"green" : "0.900",
"red" : "0.900"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.600",
"green" : "0.600",
"red" : "0.600"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.090",
"green" : "0.090",
"red" : "0.090"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.910",
"green" : "0.910",
"red" : "0.910"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.666",
"green" : "0.666",
"red" : "0.666"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.833",
"green" : "0.833",
"red" : "0.833"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

@ -0,0 +1,15 @@
//
// PodcastEpisode.swift
// PodcastsClone
//
// Created by etudiant on 2023-05-21.
//
import Foundation
struct Episode {
var id: UUID
var publicationDate: Date
var title: String
var description: String
var duration: TimeInterval // duration in seconds
}

@ -0,0 +1,89 @@
//
// PodcastEpisodeViewCell.swift
// PodcastsClone
//
// Created by etudiant on 2023-05-12.
//
import SwiftUI
struct EpisodeViewCell: View {
let episode: Episode
private let formatter: DateFormatter = {
// TODO display date smartly
// TODAY
// 1-6D AGO
// 14 MAY (no year if same year as now)
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
return formatter
}()
var body: some View {
VStack(alignment: .leading) {
// TODO make divider reach the edge on the right
Divider()
.foregroundColor(Color.theme.backgroundSecondary)
Text(formatter.string(from: episode.publicationDate))
.font(.subheadline)
.foregroundColor(Color.theme.secondary)
(Text(episode.title)
.font(.headline)
.foregroundColor(Color.theme.primary)
+ Text("\n\(episode.description)")
.font(.body)
.foregroundColor(Color.theme.secondary))
.lineLimit(4)
.truncationMode(.tail)
HStack {
Image(systemName: "play.fill")
.foregroundColor(Color.theme.accent)
.padding()
.background(Color.theme.backgroundSecondary)
.clipShape(Circle())
Text(timeString(time: episode.duration))
.foregroundColor(Color.theme.accent)
Spacer()
Text(Strings.threeDots)
.foregroundColor(Color.theme.secondary)
.padding(.horizontal)
}
}
.padding()
}
private func timeString(time: TimeInterval) -> String {
let hours = Int(time) / 3600
let minutes = Int(time) / 60 % 60
var timeComponents = [String]()
if hours > 0 {
timeComponents.append("\(hours) hr")
}
if minutes > 0 {
timeComponents.append("\(minutes) min")
}
return timeComponents.joined(separator: " ")
}
}
struct EpisodeViewCell_Previews: PreviewProvider {
static var previews: some View {
EpisodeViewCell(episode: Episode(
id: UUID(),
publicationDate: Date.now,
title: "Episode title and stuff -- what it's about, who's in it, all sorts of things can end up in this title. To us, it's a string",
description: "This is a great episode. The description kinda goes on and on and on and on and on and on and on and on.",
duration: 4000
))
}
}

@ -0,0 +1,21 @@
//
// Color.swift
// PodcastsClone
//
// Created by etudiant on 2023-05-21.
//
import Foundation
import SwiftUI
extension Color {
static let theme = ColorTheme()
}
struct ColorTheme {
let primary = Color("primary")
let secondary = Color("secondary")
let background = Color("background")
let backgroundSecondary = Color("backgroundSecondary")
let accent = Color("accent")
}

@ -42,9 +42,6 @@ struct PodcastDetailView: View {
Text("Episode View Cell goes here")
Text("Episode View Cell goes here")
}
}
.padding()
}

@ -0,0 +1,12 @@
//
// Strings.swift
// PodcastsClone
//
// Created by etudiant on 2023-05-21.
//
import Foundation
struct Strings {
static let threeDots = "···"
}

@ -1,28 +0,0 @@
//
// PodcastEpisodeViewCell.swift
// PodcastsClone
//
// Created by etudiant on 2023-05-12.
//
import SwiftUI
struct PodcastEpisodeViewCell: View {
var body: some View {
// TODO add Divider()
Text("Episode Title goes here")
// TODO add styles to episode title
// TODO add subtitle info incl duration - podcast title - by: podcast author - episode description
// TODO add play button and rounded time left (in hours, minutes...)
}
}
struct PodcastEpisodeViewCell_Previews: PreviewProvider {
static var previews: some View {
PodcastEpisodeViewCell()
}
}
Loading…
Cancel
Save