Skip to content

Commit

Permalink
[FEAT]: Implement UI for displaying top ten cryptocurrencies
Browse files Browse the repository at this point in the history
This commit introduces a new UI component for the CryptoPulse app that displays a list of the top ten cryptocurrencies. Each entry in the list includes the cryptocurrency's name, an image, and the current price, providing users with a quick overview of the market's leading assets.

Resolves: #4

[FEAT]: Implement details section UI for cryptocurrency

This commit adds a detailed UI section for displaying selected cryptocurrency information within the CryptoPulse app. The details section includes the cryptocurrency's description, a link to its official website, and historical market prices, offering users in-depth information about their chosen crypto asset.

Resolves: #5

[FEAT]: Integrate market chart for historical prices

(Optional) This commit integrates a simple market chart in the details section of the CryptoPulse app, visually representing the historical prices of the selected cryptocurrency. This feature enhances the user's ability to analyze market trends directly within the app.

Resolves: #6
  • Loading branch information
ferencIOS committed Mar 22, 2024
1 parent cf1b52f commit 71d946b
Show file tree
Hide file tree
Showing 34 changed files with 2,115 additions and 70 deletions.
14 changes: 8 additions & 6 deletions 0.application/CryptoPulse.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
130C567A2BA48EC50040DEF9 /* CryptoCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 130C56772BA48EC50040DEF9 /* CryptoCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
130C567B2BA48EC50040DEF9 /* CryptoView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 130C56782BA48EC50040DEF9 /* CryptoView.framework */; };
130C567C2BA48EC50040DEF9 /* CryptoView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 130C56782BA48EC50040DEF9 /* CryptoView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1334008F2BAC72780022678D /* CryptoLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1334008E2BAC72780022678D /* CryptoLogger.framework */; };
133400902BAC72780022678D /* CryptoLogger.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1334008E2BAC72780022678D /* CryptoLogger.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1345B79B2BA48BE300408B4A /* CryptoPulseApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1345B79A2BA48BE300408B4A /* CryptoPulseApp.swift */; };
1345B79D2BA48BE300408B4A /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1345B79C2BA48BE300408B4A /* ContentView.swift */; };
1345B79F2BA48BE400408B4A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1345B79E2BA48BE400408B4A /* Assets.xcassets */; };
1345B7A22BA48BE400408B4A /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1345B7A12BA48BE400408B4A /* Preview Assets.xcassets */; };
13CE02CD2BA48DCF00EF1910 /* CryptoNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13CE02CC2BA48DCF00EF1910 /* CryptoNetwork.framework */; };
Expand All @@ -29,6 +30,7 @@
dstSubfolderSpec = 10;
files = (
130C567A2BA48EC50040DEF9 /* CryptoCore.framework in Embed Frameworks */,
133400902BAC72780022678D /* CryptoLogger.framework in Embed Frameworks */,
130C567C2BA48EC50040DEF9 /* CryptoView.framework in Embed Frameworks */,
13DE3B4D2BA49267005F0771 /* CryptoUtilities.framework in Embed Frameworks */,
13CE02CE2BA48DCF00EF1910 /* CryptoNetwork.framework in Embed Frameworks */,
Expand All @@ -41,9 +43,9 @@
/* Begin PBXFileReference section */
130C56772BA48EC50040DEF9 /* CryptoCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
130C56782BA48EC50040DEF9 /* CryptoView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1334008E2BAC72780022678D /* CryptoLogger.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoLogger.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1345B7972BA48BE300408B4A /* CryptoPulse.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CryptoPulse.app; sourceTree = BUILT_PRODUCTS_DIR; };
1345B79A2BA48BE300408B4A /* CryptoPulseApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoPulseApp.swift; sourceTree = "<group>"; };
1345B79C2BA48BE300408B4A /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
1345B79E2BA48BE400408B4A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
1345B7A12BA48BE400408B4A /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
13CE02CC2BA48DCF00EF1910 /* CryptoNetwork.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoNetwork.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand All @@ -56,6 +58,7 @@
buildActionMask = 2147483647;
files = (
130C56792BA48EC50040DEF9 /* CryptoCore.framework in Frameworks */,
1334008F2BAC72780022678D /* CryptoLogger.framework in Frameworks */,
130C567B2BA48EC50040DEF9 /* CryptoView.framework in Frameworks */,
13DE3B4C2BA49267005F0771 /* CryptoUtilities.framework in Frameworks */,
13CE02CD2BA48DCF00EF1910 /* CryptoNetwork.framework in Frameworks */,
Expand Down Expand Up @@ -86,7 +89,6 @@
isa = PBXGroup;
children = (
1345B79A2BA48BE300408B4A /* CryptoPulseApp.swift */,
1345B79C2BA48BE300408B4A /* ContentView.swift */,
1345B79E2BA48BE400408B4A /* Assets.xcassets */,
1345B7A02BA48BE400408B4A /* Preview Content */,
);
Expand All @@ -104,6 +106,7 @@
13CE02CB2BA48DCF00EF1910 /* Frameworks */ = {
isa = PBXGroup;
children = (
1334008E2BAC72780022678D /* CryptoLogger.framework */,
13DE3B4B2BA49267005F0771 /* CryptoUtilities.framework */,
130C56772BA48EC50040DEF9 /* CryptoCore.framework */,
130C56782BA48EC50040DEF9 /* CryptoView.framework */,
Expand Down Expand Up @@ -183,7 +186,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1345B79D2BA48BE300408B4A /* ContentView.swift in Sources */,
1345B79B2BA48BE300408B4A /* CryptoPulseApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -330,7 +332,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.fs.CryptoPulse;
PRODUCT_BUNDLE_IDENTIFIER = com.fs.crypto.pulse;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
Expand Down Expand Up @@ -362,7 +364,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.fs.CryptoPulse;
PRODUCT_BUNDLE_IDENTIFIER = com.fs.crypto.pulse;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"images" : [
{
"filename" : "1024.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
Expand Down
28 changes: 0 additions & 28 deletions 0.application/CryptoPulse/ContentView.swift

This file was deleted.

5 changes: 2 additions & 3 deletions 0.application/CryptoPulse/CryptoPulseApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@
*/

import SwiftUI
import CryptoView

@main
struct CryptoPulseApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
CryptoScene()
}
}
84 changes: 82 additions & 2 deletions 1.sdks/0.view/CryptoView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,28 @@
objects = {

/* Begin PBXBuildFile section */
130B9F822BA9B0DA00225D24 /* CryptoScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130B9F812BA9B0DA00225D24 /* CryptoScene.swift */; };
130B9F852BA9CE5600225D24 /* CryptoDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130B9F842BA9CE5600225D24 /* CryptoDetailsView.swift */; };
130B9F872BA9CE6400225D24 /* CryptoDetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130B9F862BA9CE6400225D24 /* CryptoDetailsViewModel.swift */; };
130C567F2BA48ED20040DEF9 /* CryptoCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 130C567E2BA48ED20040DEF9 /* CryptoCore.framework */; };
133400972BAC91A00022678D /* ExpandableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133400962BAC91A00022678D /* ExpandableView.swift */; };
133E7FB52BA48E1D0036F83F /* CryptoView.h in Headers */ = {isa = PBXBuildFile; fileRef = 133E7FB42BA48E1D0036F83F /* CryptoView.h */; settings = {ATTRIBUTES = (Public, ); }; };
13DE3BA62BA9406B005F0771 /* MVI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13DE3BA52BA9406B005F0771 /* MVI.swift */; };
13DE3BAF2BA9484D005F0771 /* CryptoListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13DE3BAE2BA9484D005F0771 /* CryptoListViewModel.swift */; };
13DE3BB12BA948A0005F0771 /* CryptoListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13DE3BB02BA948A0005F0771 /* CryptoListView.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
130B9F812BA9B0DA00225D24 /* CryptoScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoScene.swift; sourceTree = "<group>"; };
130B9F842BA9CE5600225D24 /* CryptoDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoDetailsView.swift; sourceTree = "<group>"; };
130B9F862BA9CE6400225D24 /* CryptoDetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoDetailsViewModel.swift; sourceTree = "<group>"; };
130C567E2BA48ED20040DEF9 /* CryptoCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
133400962BAC91A00022678D /* ExpandableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableView.swift; sourceTree = "<group>"; };
133E7FB12BA48E1D0036F83F /* CryptoView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CryptoView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
133E7FB42BA48E1D0036F83F /* CryptoView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CryptoView.h; sourceTree = "<group>"; };
13DE3BA52BA9406B005F0771 /* MVI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVI.swift; sourceTree = "<group>"; };
13DE3BAE2BA9484D005F0771 /* CryptoListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoListViewModel.swift; sourceTree = "<group>"; };
13DE3BB02BA948A0005F0771 /* CryptoListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoListView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -29,6 +43,15 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
130B9F832BA9CE3300225D24 /* details */ = {
isa = PBXGroup;
children = (
130B9F842BA9CE5600225D24 /* CryptoDetailsView.swift */,
130B9F862BA9CE6400225D24 /* CryptoDetailsViewModel.swift */,
);
path = details;
sourceTree = "<group>";
};
130C567D2BA48ED20040DEF9 /* Frameworks */ = {
isa = PBXGroup;
children = (
Expand All @@ -37,6 +60,14 @@
name = Frameworks;
sourceTree = "<group>";
};
133400952BAC918B0022678D /* helpers */ = {
isa = PBXGroup;
children = (
133400962BAC91A00022678D /* ExpandableView.swift */,
);
path = helpers;
sourceTree = "<group>";
};
133E7FA72BA48E1C0036F83F = {
isa = PBXGroup;
children = (
Expand All @@ -58,10 +89,48 @@
isa = PBXGroup;
children = (
133E7FB42BA48E1D0036F83F /* CryptoView.h */,
13DE3BB22BA9545E005F0771 /* system-handler */,
13DE3BA72BA94171005F0771 /* screens */,
13DE3BA42BA9403D005F0771 /* mvi */,
133400952BAC918B0022678D /* helpers */,
);
path = CryptoView;
sourceTree = "<group>";
};
13DE3BA42BA9403D005F0771 /* mvi */ = {
isa = PBXGroup;
children = (
13DE3BA52BA9406B005F0771 /* MVI.swift */,
);
path = mvi;
sourceTree = "<group>";
};
13DE3BA72BA94171005F0771 /* screens */ = {
isa = PBXGroup;
children = (
13DE3BAD2BA947F4005F0771 /* list */,
130B9F832BA9CE3300225D24 /* details */,
);
path = screens;
sourceTree = "<group>";
};
13DE3BAD2BA947F4005F0771 /* list */ = {
isa = PBXGroup;
children = (
13DE3BB02BA948A0005F0771 /* CryptoListView.swift */,
13DE3BAE2BA9484D005F0771 /* CryptoListViewModel.swift */,
);
path = list;
sourceTree = "<group>";
};
13DE3BB22BA9545E005F0771 /* system-handler */ = {
isa = PBXGroup;
children = (
130B9F812BA9B0DA00225D24 /* CryptoScene.swift */,
);
path = "system-handler";
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand Down Expand Up @@ -105,6 +174,7 @@
TargetAttributes = {
133E7FB02BA48E1D0036F83F = {
CreatedOnToolsVersion = 15.3;
LastSwiftMigration = 1530;
};
};
};
Expand Down Expand Up @@ -141,6 +211,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
13DE3BA62BA9406B005F0771 /* MVI.swift in Sources */,
13DE3BAF2BA9484D005F0771 /* CryptoListViewModel.swift in Sources */,
133400972BAC91A00022678D /* ExpandableView.swift in Sources */,
130B9F852BA9CE5600225D24 /* CryptoDetailsView.swift in Sources */,
13DE3BB12BA948A0005F0771 /* CryptoListView.swift in Sources */,
130B9F872BA9CE6400225D24 /* CryptoDetailsViewModel.swift in Sources */,
130B9F822BA9B0DA00225D24 /* CryptoScene.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -276,6 +353,7 @@
isa = XCBuildConfiguration;
buildSettings = {
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
Expand All @@ -294,7 +372,7 @@
MARKETING_VERSION = 1.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
PRODUCT_BUNDLE_IDENTIFIER = com.fs.CryptoView;
PRODUCT_BUNDLE_IDENTIFIER = com.fs.crypto.view;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand All @@ -303,6 +381,7 @@
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
Expand All @@ -312,6 +391,7 @@
isa = XCBuildConfiguration;
buildSettings = {
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
Expand All @@ -330,7 +410,7 @@
MARKETING_VERSION = 1.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
PRODUCT_BUNDLE_IDENTIFIER = com.fs.CryptoView;
PRODUCT_BUNDLE_IDENTIFIER = com.fs.crypto.view;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand Down
55 changes: 55 additions & 0 deletions 1.sdks/0.view/CryptoView/helpers/ExpandableView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// ExpandableView.swift
// CryptoView
//
// Created by francesco scalise on 21/03/24.
//

import SwiftUI

struct ExpandableView: View {
@State private var isExpanded = false

private let headerText: String
private let bodyText: String

private let textStyle: Font = .body
private let textColor: Color = .white

private let previewLimit: Int = 100

public init(fullText: String) {
if fullText.count > previewLimit {
let index = fullText.index(fullText.startIndex, offsetBy: previewLimit)
self.headerText = String(fullText[..<index]) + "..."
self.bodyText = String(fullText[index...])
} else {
self.headerText = fullText
self.bodyText = ""
}
}

var body: some View {
VStack(alignment: .leading) {
if !isExpanded {
Text(headerText)
.font(textStyle)
.foregroundColor(textColor)
.onTapGesture {
withAnimation {
self.isExpanded.toggle()
}
}
} else {
Text(headerText.dropLast(3) + bodyText)
.font(textStyle)
.foregroundColor(textColor)
.onTapGesture {
withAnimation {
self.isExpanded.toggle()
}
}
}
}
}
}
Loading

0 comments on commit 71d946b

Please sign in to comment.