summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Segundo2023-07-24 10:45:15 +0200
committerChristian Segundo2023-07-24 10:45:15 +0200
commit01ce93653d86f2a47eda58d2e74c3926981b22cf (patch)
treedef1c1599a0a044ab9c64d48b89c704f4cbb0938
parent864b644e8ecafccaf84b40168524e47351a6d111 (diff)
downloadxmission-ios-master.tar.gz
-rw-r--r--.gitignore1
-rw-r--r--Xmission.xcodeproj/project.pbxproj158
-rw-r--r--Xmission.xcodeproj/xcshareddata/xcschemes/Xmission.xcscheme101
-rw-r--r--Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist6
-rw-r--r--Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcschemes/xcschememanagement.plist18
-rw-r--r--Xmission/Code/Home/Actions/AddTorrent.swift8
-rw-r--r--Xmission/Code/Home/Actions/DeleteTorrent.swift8
-rw-r--r--Xmission/Code/Home/Actions/LoginAction.swift52
-rw-r--r--Xmission/Code/Home/Models/ListTorrentResponse.swift12
-rw-r--r--Xmission/Code/Home/Models/LoginRequest.swift6
-rw-r--r--Xmission/Code/Home/Models/LoginResponse.swift10
-rw-r--r--Xmission/Code/Home/Screens/HomeScreen.swift89
-rw-r--r--Xmission/Code/Home/ViewModels/HomeViewModel.swift35
-rw-r--r--Xmission/Code/Utilities/Extensions/StringExtensions.swift11
-rw-r--r--Xmission/ContentView.swift26
-rw-r--r--Xmission/SupportingFiles/Localization/en.lproj/Localizable.strings8
-rw-r--r--Xmission/SupportingFiles/Localization/es.lproj/Localizable.strings7
-rw-r--r--Xmission/Xmission.entitlements8
-rw-r--r--Xmission/XmissionApp.swift2
19 files changed, 523 insertions, 43 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e43b0f9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.DS_Store
diff --git a/Xmission.xcodeproj/project.pbxproj b/Xmission.xcodeproj/project.pbxproj
index 168d46c..1a1ba55 100644
--- a/Xmission.xcodeproj/project.pbxproj
+++ b/Xmission.xcodeproj/project.pbxproj
@@ -8,12 +8,21 @@
/* Begin PBXBuildFile section */
1E244F162A353D340052909D /* XmissionApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E244F152A353D340052909D /* XmissionApp.swift */; };
- 1E244F182A353D340052909D /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E244F172A353D340052909D /* ContentView.swift */; };
1E244F1A2A353D360052909D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1E244F192A353D360052909D /* Assets.xcassets */; };
1E244F1E2A353D360052909D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1E244F1D2A353D360052909D /* Preview Assets.xcassets */; };
1E244F282A353D360052909D /* XmissionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E244F272A353D360052909D /* XmissionTests.swift */; };
1E244F322A353D360052909D /* XmissionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E244F312A353D360052909D /* XmissionUITests.swift */; };
1E244F342A353D360052909D /* XmissionUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E244F332A353D360052909D /* XmissionUITestsLaunchTests.swift */; };
+ 1E7B64B62A6B32DB00C5BBCB /* LoginRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64B52A6B32DB00C5BBCB /* LoginRequest.swift */; };
+ 1E7B64B82A6B32EE00C5BBCB /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64B72A6B32EE00C5BBCB /* HomeScreen.swift */; };
+ 1E7B64BA2A6B32FD00C5BBCB /* HomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64B92A6B32FD00C5BBCB /* HomeViewModel.swift */; };
+ 1E7B64C12A6B33A600C5BBCB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1E7B64C32A6B33A600C5BBCB /* Localizable.strings */; };
+ 1E7B64C92A6B34C000C5BBCB /* StringExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64C82A6B34C000C5BBCB /* StringExtensions.swift */; };
+ 1E7B64CC2A6B350600C5BBCB /* LoginAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64CB2A6B350600C5BBCB /* LoginAction.swift */; };
+ 1E7B64CE2A6B356F00C5BBCB /* LoginResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64CD2A6B356F00C5BBCB /* LoginResponse.swift */; };
+ 1E7B64D02A6B465200C5BBCB /* ListTorrentResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64CF2A6B465200C5BBCB /* ListTorrentResponse.swift */; };
+ 1E7B64D22A6B48DB00C5BBCB /* AddTorrent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64D12A6B48DB00C5BBCB /* AddTorrent.swift */; };
+ 1E7B64D42A6B48E900C5BBCB /* DeleteTorrent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7B64D32A6B48E900C5BBCB /* DeleteTorrent.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -36,7 +45,6 @@
/* Begin PBXFileReference section */
1E244F122A353D340052909D /* Xmission.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Xmission.app; sourceTree = BUILT_PRODUCTS_DIR; };
1E244F152A353D340052909D /* XmissionApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XmissionApp.swift; sourceTree = "<group>"; };
- 1E244F172A353D340052909D /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
1E244F192A353D360052909D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
1E244F1B2A353D360052909D /* Xmission.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Xmission.entitlements; sourceTree = "<group>"; };
1E244F1D2A353D360052909D /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
@@ -45,6 +53,17 @@
1E244F2D2A353D360052909D /* XmissionUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XmissionUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
1E244F312A353D360052909D /* XmissionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XmissionUITests.swift; sourceTree = "<group>"; };
1E244F332A353D360052909D /* XmissionUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XmissionUITestsLaunchTests.swift; sourceTree = "<group>"; };
+ 1E7B64B52A6B32DB00C5BBCB /* LoginRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginRequest.swift; sourceTree = "<group>"; };
+ 1E7B64B72A6B32EE00C5BBCB /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
+ 1E7B64B92A6B32FD00C5BBCB /* HomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModel.swift; sourceTree = "<group>"; };
+ 1E7B64C22A6B33A600C5BBCB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 1E7B64C42A6B33DE00C5BBCB /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 1E7B64C82A6B34C000C5BBCB /* StringExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtensions.swift; sourceTree = "<group>"; };
+ 1E7B64CB2A6B350600C5BBCB /* LoginAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginAction.swift; sourceTree = "<group>"; };
+ 1E7B64CD2A6B356F00C5BBCB /* LoginResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginResponse.swift; sourceTree = "<group>"; };
+ 1E7B64CF2A6B465200C5BBCB /* ListTorrentResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTorrentResponse.swift; sourceTree = "<group>"; };
+ 1E7B64D12A6B48DB00C5BBCB /* AddTorrent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddTorrent.swift; sourceTree = "<group>"; };
+ 1E7B64D32A6B48E900C5BBCB /* DeleteTorrent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteTorrent.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -95,8 +114,9 @@
1E244F142A353D340052909D /* Xmission */ = {
isa = PBXGroup;
children = (
+ 1E7B64BB2A6B335200C5BBCB /* SupportingFiles */,
+ 1E7B64B12A6B326800C5BBCB /* Code */,
1E244F152A353D340052909D /* XmissionApp.swift */,
- 1E244F172A353D340052909D /* ContentView.swift */,
1E244F192A353D360052909D /* Assets.xcassets */,
1E244F1B2A353D360052909D /* Xmission.entitlements */,
1E244F1C2A353D360052909D /* Preview Content */,
@@ -129,6 +149,94 @@
path = XmissionUITests;
sourceTree = "<group>";
};
+ 1E7B64B12A6B326800C5BBCB /* Code */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64C62A6B34A800C5BBCB /* Home */,
+ 1E7B64C52A6B349D00C5BBCB /* Utilities */,
+ );
+ path = Code;
+ sourceTree = "<group>";
+ };
+ 1E7B64B22A6B32A600C5BBCB /* Models */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64B52A6B32DB00C5BBCB /* LoginRequest.swift */,
+ 1E7B64CD2A6B356F00C5BBCB /* LoginResponse.swift */,
+ 1E7B64CF2A6B465200C5BBCB /* ListTorrentResponse.swift */,
+ );
+ path = Models;
+ sourceTree = "<group>";
+ };
+ 1E7B64B32A6B32AD00C5BBCB /* Screens */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64B72A6B32EE00C5BBCB /* HomeScreen.swift */,
+ );
+ path = Screens;
+ sourceTree = "<group>";
+ };
+ 1E7B64B42A6B32B100C5BBCB /* ViewModels */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64B92A6B32FD00C5BBCB /* HomeViewModel.swift */,
+ );
+ path = ViewModels;
+ sourceTree = "<group>";
+ };
+ 1E7B64BB2A6B335200C5BBCB /* SupportingFiles */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64BC2A6B335B00C5BBCB /* Localization */,
+ );
+ path = SupportingFiles;
+ sourceTree = "<group>";
+ };
+ 1E7B64BC2A6B335B00C5BBCB /* Localization */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64C32A6B33A600C5BBCB /* Localizable.strings */,
+ );
+ path = Localization;
+ sourceTree = "<group>";
+ };
+ 1E7B64C52A6B349D00C5BBCB /* Utilities */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64C72A6B34B300C5BBCB /* Extensions */,
+ );
+ path = Utilities;
+ sourceTree = "<group>";
+ };
+ 1E7B64C62A6B34A800C5BBCB /* Home */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64CA2A6B34F800C5BBCB /* Actions */,
+ 1E7B64B42A6B32B100C5BBCB /* ViewModels */,
+ 1E7B64B32A6B32AD00C5BBCB /* Screens */,
+ 1E7B64B22A6B32A600C5BBCB /* Models */,
+ );
+ path = Home;
+ sourceTree = "<group>";
+ };
+ 1E7B64C72A6B34B300C5BBCB /* Extensions */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64C82A6B34C000C5BBCB /* StringExtensions.swift */,
+ );
+ path = Extensions;
+ sourceTree = "<group>";
+ };
+ 1E7B64CA2A6B34F800C5BBCB /* Actions */ = {
+ isa = PBXGroup;
+ children = (
+ 1E7B64CB2A6B350600C5BBCB /* LoginAction.swift */,
+ 1E7B64D12A6B48DB00C5BBCB /* AddTorrent.swift */,
+ 1E7B64D32A6B48E900C5BBCB /* DeleteTorrent.swift */,
+ );
+ path = Actions;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -215,6 +323,7 @@
knownRegions = (
en,
Base,
+ es,
);
mainGroup = 1E244F092A353D340052909D;
productRefGroup = 1E244F132A353D340052909D /* Products */;
@@ -234,6 +343,7 @@
buildActionMask = 2147483647;
files = (
1E244F1E2A353D360052909D /* Preview Assets.xcassets in Resources */,
+ 1E7B64C12A6B33A600C5BBCB /* Localizable.strings in Resources */,
1E244F1A2A353D360052909D /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -259,8 +369,16 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 1E244F182A353D340052909D /* ContentView.swift in Sources */,
+ 1E7B64C92A6B34C000C5BBCB /* StringExtensions.swift in Sources */,
+ 1E7B64B62A6B32DB00C5BBCB /* LoginRequest.swift in Sources */,
+ 1E7B64D22A6B48DB00C5BBCB /* AddTorrent.swift in Sources */,
+ 1E7B64D02A6B465200C5BBCB /* ListTorrentResponse.swift in Sources */,
+ 1E7B64B82A6B32EE00C5BBCB /* HomeScreen.swift in Sources */,
+ 1E7B64BA2A6B32FD00C5BBCB /* HomeViewModel.swift in Sources */,
+ 1E7B64D42A6B48E900C5BBCB /* DeleteTorrent.swift in Sources */,
1E244F162A353D340052909D /* XmissionApp.swift in Sources */,
+ 1E7B64CE2A6B356F00C5BBCB /* LoginResponse.swift in Sources */,
+ 1E7B64CC2A6B350600C5BBCB /* LoginAction.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -296,11 +414,24 @@
};
/* End PBXTargetDependency section */
+/* Begin PBXVariantGroup section */
+ 1E7B64C32A6B33A600C5BBCB /* Localizable.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 1E7B64C22A6B33A600C5BBCB /* en */,
+ 1E7B64C42A6B33DE00C5BBCB /* es */,
+ );
+ name = Localizable.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
/* Begin XCBuildConfiguration section */
1E244F352A353D360052909D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
@@ -359,6 +490,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
@@ -411,12 +543,14 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CODE_SIGN_ENTITLEMENTS = Xmission/Xmission.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Xmission/Preview Content\"";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@@ -425,17 +559,16 @@
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
- INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
- INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
- MACOSX_DEPLOYMENT_TARGET = 13.3;
+ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = segundo.io.Xmission;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -447,12 +580,14 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CODE_SIGN_ENTITLEMENTS = Xmission/Xmission.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Xmission/Preview Content\"";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@@ -461,17 +596,16 @@
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
- INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
- INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
- MACOSX_DEPLOYMENT_TARGET = 13.3;
+ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = segundo.io.Xmission;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/Xmission.xcodeproj/xcshareddata/xcschemes/Xmission.xcscheme b/Xmission.xcodeproj/xcshareddata/xcschemes/Xmission.xcscheme
new file mode 100644
index 0000000..550c528
--- /dev/null
+++ b/Xmission.xcodeproj/xcshareddata/xcschemes/Xmission.xcscheme
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "1430"
+ version = "1.7">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "1E244F112A353D340052909D"
+ BuildableName = "Xmission.app"
+ BlueprintName = "Xmission"
+ ReferencedContainer = "container:Xmission.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ shouldAutocreateTestPlan = "YES">
+ <Testables>
+ <TestableReference
+ skipped = "NO"
+ parallelizable = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "1E244F222A353D360052909D"
+ BuildableName = "XmissionTests.xctest"
+ BlueprintName = "XmissionTests"
+ ReferencedContainer = "container:Xmission.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ <TestableReference
+ skipped = "NO"
+ parallelizable = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "1E244F2C2A353D360052909D"
+ BuildableName = "XmissionUITests.xctest"
+ BlueprintName = "XmissionUITests"
+ ReferencedContainer = "container:Xmission.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "1E244F112A353D340052909D"
+ BuildableName = "Xmission.app"
+ BlueprintName = "Xmission"
+ ReferencedContainer = "container:Xmission.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "1E244F112A353D340052909D"
+ BuildableName = "Xmission.app"
+ BlueprintName = "Xmission"
+ ReferencedContainer = "container:Xmission.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
new file mode 100644
index 0000000..f99372c
--- /dev/null
+++ b/Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Bucket
+ uuid = "FD7683EF-D385-48C7-B53B-DE469A66CC7E"
+ type = "1"
+ version = "2.0">
+</Bucket>
diff --git a/Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcschemes/xcschememanagement.plist b/Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcschemes/xcschememanagement.plist
index ef901ab..a0a89fd 100644
--- a/Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/Xmission.xcodeproj/xcuserdata/christian.segundo.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -10,5 +10,23 @@
<integer>0</integer>
</dict>
</dict>
+ <key>SuppressBuildableAutocreation</key>
+ <dict>
+ <key>1E244F112A353D340052909D</key>
+ <dict>
+ <key>primary</key>
+ <true/>
+ </dict>
+ <key>1E244F222A353D360052909D</key>
+ <dict>
+ <key>primary</key>
+ <true/>
+ </dict>
+ <key>1E244F2C2A353D360052909D</key>
+ <dict>
+ <key>primary</key>
+ <true/>
+ </dict>
+ </dict>
</dict>
</plist>
diff --git a/Xmission/Code/Home/Actions/AddTorrent.swift b/Xmission/Code/Home/Actions/AddTorrent.swift
new file mode 100644
index 0000000..70dae56
--- /dev/null
+++ b/Xmission/Code/Home/Actions/AddTorrent.swift
@@ -0,0 +1,8 @@
+//
+// AddTorrent.swift
+// Xmission
+//
+// Created by Christian Segundo Guevara on 22/7/23.
+//
+
+import Foundation
diff --git a/Xmission/Code/Home/Actions/DeleteTorrent.swift b/Xmission/Code/Home/Actions/DeleteTorrent.swift
new file mode 100644
index 0000000..5fcf494
--- /dev/null
+++ b/Xmission/Code/Home/Actions/DeleteTorrent.swift
@@ -0,0 +1,8 @@
+//
+// DeleteTorrent.swift
+// Xmission
+//
+// Created by Christian Segundo Guevara on 22/7/23.
+//
+
+import Foundation
diff --git a/Xmission/Code/Home/Actions/LoginAction.swift b/Xmission/Code/Home/Actions/LoginAction.swift
new file mode 100644
index 0000000..81fa97c
--- /dev/null
+++ b/Xmission/Code/Home/Actions/LoginAction.swift
@@ -0,0 +1,52 @@
+import Foundation
+
+struct LoginAction {
+
+ var parameters: LoginRequest
+
+ func call(completion: @escaping (LoginResponse) -> Void) {
+
+ let scheme: String = "https"
+ let host: String = "base_url"
+ let path = "/login"
+
+ var components = URLComponents()
+ components.scheme = scheme
+ components.host = host
+ components.path = path
+
+ guard let url = components.url else {
+ return
+ }
+
+ var request = URLRequest(url: url)
+ request.httpMethod = "post"
+
+ request.addValue("application/json", forHTTPHeaderField: "Content-Type")
+ request.addValue("application/json", forHTTPHeaderField: "Accept")
+
+ do {
+ request.httpBody = try JSONEncoder().encode(parameters)
+ } catch {
+ // Error: Unable to encode request parameters
+ }
+
+ let task = URLSession.shared.dataTask(with: request) { data, _, error in
+ if let data = data {
+ let response = try? JSONDecoder().decode(LoginResponse.self, from: data)
+
+ if let response = response {
+ completion(response)
+ } else {
+ // Error: Unable to decode response JSON
+ }
+ } else {
+ // Error: API request failed
+ if let error = error {
+ print("Error: \(error.localizedDescription)")
+ }
+ }
+ }
+ task.resume()
+ }
+}
diff --git a/Xmission/Code/Home/Models/ListTorrentResponse.swift b/Xmission/Code/Home/Models/ListTorrentResponse.swift
new file mode 100644
index 0000000..42331cd
--- /dev/null
+++ b/Xmission/Code/Home/Models/ListTorrentResponse.swift
@@ -0,0 +1,12 @@
+import Foundation
+
+typealias ListTorrentResponse = [Torrent]
+
+struct Torrent: Decodable {
+ var name: String
+ var completionPercent: Float
+ let ratio: Float
+ let rateDownload: Int64
+ let rateUpload: Int64
+ let labels: [String]
+}
diff --git a/Xmission/Code/Home/Models/LoginRequest.swift b/Xmission/Code/Home/Models/LoginRequest.swift
new file mode 100644
index 0000000..40ef3f6
--- /dev/null
+++ b/Xmission/Code/Home/Models/LoginRequest.swift
@@ -0,0 +1,6 @@
+import Foundation
+
+struct LoginRequest: Encodable {
+ let username: String
+ let password: String
+}
diff --git a/Xmission/Code/Home/Models/LoginResponse.swift b/Xmission/Code/Home/Models/LoginResponse.swift
new file mode 100644
index 0000000..51bd864
--- /dev/null
+++ b/Xmission/Code/Home/Models/LoginResponse.swift
@@ -0,0 +1,10 @@
+import Foundation
+
+struct LoginResponse: Decodable {
+ let data: LoginResponseData
+}
+
+struct LoginResponseData: Decodable {
+ let accessToken: String
+ let refreshToken: String
+}
diff --git a/Xmission/Code/Home/Screens/HomeScreen.swift b/Xmission/Code/Home/Screens/HomeScreen.swift
new file mode 100644
index 0000000..dac8a20
--- /dev/null
+++ b/Xmission/Code/Home/Screens/HomeScreen.swift
@@ -0,0 +1,89 @@
+import SwiftUI
+
+struct HomeScreen: View {
+ @ObservedObject var viewModel: HomeViewModel = .init()
+
+ var body: some View {
+ NavigationView {
+ List {
+ ForEach(viewModel.torrents, id: \.name) { torrent in
+ TorrentRow(torrent: torrent)
+ .swipeActions(edge: .trailing) {
+ Button {} label: {
+ Label("Delete", systemImage: "trash")
+ }
+ .tint(.red)
+ }
+ .listRowSeparator(.hidden)
+ }
+ }
+ .listStyle(.plain)
+
+ .navigationBarTitle(Text("192.168.0.2"), displayMode: .inline)
+ .navigationBarItems(
+ leading: Button(
+ action: { print("Adding torrent") },
+ label: { Image(systemName: "plus") }
+ ),
+ trailing:
+ Button(
+ action: { print("Going to Settings") },
+ label: { Image(systemName: "gear") }
+ )
+ )
+ }
+ }
+}
+
+struct TorrentRow: View {
+ let torrent: Torrent
+
+ var body: some View {
+ HStack {
+ ProgressView(
+ value: torrent.completionPercent,
+ total: 100,
+ label: {
+ VStack {
+ Text(torrent.name)
+ HStack {
+ // todo chips
+ }
+ }
+ },
+ currentValueLabel: {
+ HStack {
+ Text("Ratio: " + String(torrent.ratio)).frame(
+ maxWidth: .infinity,
+ maxHeight: .infinity,
+ alignment: .leading
+ )
+
+ Text(String(torrent.completionPercent) + "%").frame(
+ maxWidth: .infinity,
+ maxHeight: .infinity,
+ alignment: .center
+ )
+
+ HStack {
+ Image(systemName: "chevron.up", variableValue: 100)
+ Text(String(torrent.rateUpload))
+ Image(systemName: "chevron.down")
+ Text(String(torrent.rateDownload))
+ }.frame(
+ maxWidth: .infinity,
+ maxHeight: .infinity,
+ alignment: .trailing
+ )
+ }
+ }
+ )
+ }
+ }
+}
+
+struct HomeScreen_Previews: PreviewProvider {
+ static var previews: some View {
+ HomeScreen()
+ }
+}
diff --git a/Xmission/Code/Home/ViewModels/HomeViewModel.swift b/Xmission/Code/Home/ViewModels/HomeViewModel.swift
new file mode 100644
index 0000000..f1b95e5
--- /dev/null
+++ b/Xmission/Code/Home/ViewModels/HomeViewModel.swift
@@ -0,0 +1,35 @@
+import Foundation
+
+class HomeViewModel: ObservableObject {
+ @Published var torrents: ListTorrentResponse = []
+
+ var timer: Timer?
+
+ init() {
+ timer = Timer.scheduledTimer(
+ withTimeInterval: 1,
+ repeats: true,
+ block: { _ in
+ self.refresh()
+ }
+ )
+ }
+
+ deinit {
+ timer?.invalidate()
+ }
+
+ func refresh() {
+ let randomFloat = Float.random(in: 1 ..< 100)
+
+ torrents = [
+ Torrent(
+ name: "foo",
+ completionPercent: randomFloat, ratio: 0,
+ rateDownload: 1,
+ rateUpload: 1,
+ labels: ["foo", "bar"]
+ )
+ ]
+ }
+}
diff --git a/Xmission/Code/Utilities/Extensions/StringExtensions.swift b/Xmission/Code/Utilities/Extensions/StringExtensions.swift
new file mode 100644
index 0000000..5e7455d
--- /dev/null
+++ b/Xmission/Code/Utilities/Extensions/StringExtensions.swift
@@ -0,0 +1,11 @@
+import Foundation
+
+extension String {
+ var localized: String {
+ return NSLocalizedString(self, comment: "")
+ }
+
+ func localized(arguments: CVarArg...) -> String {
+ return String(format: localized, arguments: arguments)
+ }
+}
diff --git a/Xmission/ContentView.swift b/Xmission/ContentView.swift
deleted file mode 100644
index 0487cfa..0000000
--- a/Xmission/ContentView.swift
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// ContentView.swift
-// Xmission
-//
-// Created by Christian Segundo Guevara on 11/6/23.
-//
-
-import SwiftUI
-
-struct ContentView: View {
- var body: some View {
- VStack {
- Image(systemName: "globe")
- .imageScale(.large)
- .foregroundColor(.accentColor)
- Text("Hello, world!")
- }
- .padding()
- }
-}
-
-struct ContentView_Previews: PreviewProvider {
- static var previews: some View {
- ContentView()
- }
-}
diff --git a/Xmission/SupportingFiles/Localization/en.lproj/Localizable.strings b/Xmission/SupportingFiles/Localization/en.lproj/Localizable.strings
new file mode 100644
index 0000000..0258758
--- /dev/null
+++ b/Xmission/SupportingFiles/Localization/en.lproj/Localizable.strings
@@ -0,0 +1,8 @@
+/*
+ Localizable.strings
+ Xmission
+
+ Created by Christian Segundo Guevara on 21/7/23.
+
+*/
+
diff --git a/Xmission/SupportingFiles/Localization/es.lproj/Localizable.strings b/Xmission/SupportingFiles/Localization/es.lproj/Localizable.strings
new file mode 100644
index 0000000..b330103
--- /dev/null
+++ b/Xmission/SupportingFiles/Localization/es.lproj/Localizable.strings
@@ -0,0 +1,7 @@
+/*
+ Localizable.strings
+ Xmission
+
+ Created by Christian Segundo Guevara on 21/7/23.
+
+*/
diff --git a/Xmission/Xmission.entitlements b/Xmission/Xmission.entitlements
index f2ef3ae..18aff0c 100644
--- a/Xmission/Xmission.entitlements
+++ b/Xmission/Xmission.entitlements
@@ -2,9 +2,9 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>com.apple.security.app-sandbox</key>
- <true/>
- <key>com.apple.security.files.user-selected.read-only</key>
- <true/>
+ <key>com.apple.security.app-sandbox</key>
+ <true/>
+ <key>com.apple.security.files.user-selected.read-only</key>
+ <true/>
</dict>
</plist>
diff --git a/Xmission/XmissionApp.swift b/Xmission/XmissionApp.swift
index cc2719b..e5ef0f3 100644
--- a/Xmission/XmissionApp.swift
+++ b/Xmission/XmissionApp.swift
@@ -11,7 +11,7 @@ import SwiftUI
struct XmissionApp: App {
var body: some Scene {
WindowGroup {
- ContentView()
+ HomeScreen()
}
}
}