Showing
7 changed files
with
226 additions
and
3 deletions
... | @@ -19,6 +19,7 @@ | ... | @@ -19,6 +19,7 @@ |
19 | 1EBEB02D280D69D800BF802C /* GiftsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EBEB02C280D69D800BF802C /* GiftsView.swift */; }; | 19 | 1EBEB02D280D69D800BF802C /* GiftsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EBEB02C280D69D800BF802C /* GiftsView.swift */; }; |
20 | 1EBEB02F280D6AA500BF802C /* GiftsViewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EBEB02E280D6AA500BF802C /* GiftsViewInterface.swift */; }; | 20 | 1EBEB02F280D6AA500BF802C /* GiftsViewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EBEB02E280D6AA500BF802C /* GiftsViewInterface.swift */; }; |
21 | 260C6A1AFF7560C32E212F20 /* Pods_WarplySDKFrameworkIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1353B8C484CC0649CAC2EB74 /* Pods_WarplySDKFrameworkIOS.framework */; }; | 21 | 260C6A1AFF7560C32E212F20 /* Pods_WarplySDKFrameworkIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1353B8C484CC0649CAC2EB74 /* Pods_WarplySDKFrameworkIOS.framework */; }; |
22 | + E634A362282151E30069DE27 /* StepsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E634A361282151E30069DE27 /* StepsView.swift */; }; | ||
22 | E639EFA2280810E300B9DD94 /* CouponsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E639EFA0280810E300B9DD94 /* CouponsView.swift */; }; | 23 | E639EFA2280810E300B9DD94 /* CouponsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E639EFA0280810E300B9DD94 /* CouponsView.swift */; }; |
23 | E639EFA3280810E300B9DD94 /* CouponsViewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = E639EFA1280810E300B9DD94 /* CouponsViewInterface.swift */; }; | 24 | E639EFA3280810E300B9DD94 /* CouponsViewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = E639EFA1280810E300B9DD94 /* CouponsViewInterface.swift */; }; |
24 | E639EFA52808244E00B9DD94 /* MyEmptyClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E639EFA42808244E00B9DD94 /* MyEmptyClass.swift */; }; | 25 | E639EFA52808244E00B9DD94 /* MyEmptyClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = E639EFA42808244E00B9DD94 /* MyEmptyClass.swift */; }; |
... | @@ -159,6 +160,7 @@ | ... | @@ -159,6 +160,7 @@ |
159 | 1EBEB02C280D69D800BF802C /* GiftsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GiftsView.swift; sourceTree = "<group>"; }; | 160 | 1EBEB02C280D69D800BF802C /* GiftsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GiftsView.swift; sourceTree = "<group>"; }; |
160 | 1EBEB02E280D6AA500BF802C /* GiftsViewInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GiftsViewInterface.swift; sourceTree = "<group>"; }; | 161 | 1EBEB02E280D6AA500BF802C /* GiftsViewInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GiftsViewInterface.swift; sourceTree = "<group>"; }; |
161 | B9413513157AD76ECE896B81 /* Pods-WarplySDKFrameworkIOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WarplySDKFrameworkIOS.release.xcconfig"; path = "Target Support Files/Pods-WarplySDKFrameworkIOS/Pods-WarplySDKFrameworkIOS.release.xcconfig"; sourceTree = "<group>"; }; | 162 | B9413513157AD76ECE896B81 /* Pods-WarplySDKFrameworkIOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WarplySDKFrameworkIOS.release.xcconfig"; path = "Target Support Files/Pods-WarplySDKFrameworkIOS/Pods-WarplySDKFrameworkIOS.release.xcconfig"; sourceTree = "<group>"; }; |
163 | + E634A361282151E30069DE27 /* StepsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StepsView.swift; sourceTree = "<group>"; }; | ||
162 | E639EFA0280810E300B9DD94 /* CouponsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CouponsView.swift; sourceTree = "<group>"; }; | 164 | E639EFA0280810E300B9DD94 /* CouponsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CouponsView.swift; sourceTree = "<group>"; }; |
163 | E639EFA1280810E300B9DD94 /* CouponsViewInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CouponsViewInterface.swift; sourceTree = "<group>"; }; | 165 | E639EFA1280810E300B9DD94 /* CouponsViewInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CouponsViewInterface.swift; sourceTree = "<group>"; }; |
164 | E639EFA42808244E00B9DD94 /* MyEmptyClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyEmptyClass.swift; sourceTree = "<group>"; }; | 166 | E639EFA42808244E00B9DD94 /* MyEmptyClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyEmptyClass.swift; sourceTree = "<group>"; }; |
... | @@ -376,6 +378,7 @@ | ... | @@ -376,6 +378,7 @@ |
376 | E655D05928058A72004F913C /* WarplySDKFrameworkIOS-Bridging-Header.h */, | 378 | E655D05928058A72004F913C /* WarplySDKFrameworkIOS-Bridging-Header.h */, |
377 | E639EFA42808244E00B9DD94 /* MyEmptyClass.swift */, | 379 | E639EFA42808244E00B9DD94 /* MyEmptyClass.swift */, |
378 | E67D1EC528117F2400940F01 /* swiftApi.swift */, | 380 | E67D1EC528117F2400940F01 /* swiftApi.swift */, |
381 | + E634A361282151E30069DE27 /* StepsView.swift */, | ||
379 | ); | 382 | ); |
380 | path = WarplySDKFrameworkIOS; | 383 | path = WarplySDKFrameworkIOS; |
381 | sourceTree = "<group>"; | 384 | sourceTree = "<group>"; |
... | @@ -805,6 +808,7 @@ | ... | @@ -805,6 +808,7 @@ |
805 | E67D1EB8281055D900940F01 /* WalletViewInterface.swift in Sources */, | 808 | E67D1EB8281055D900940F01 /* WalletViewInterface.swift in Sources */, |
806 | E6D8DF3127A942920006A3A9 /* AFNetworkActivityIndicatorManager.m in Sources */, | 809 | E6D8DF3127A942920006A3A9 /* AFNetworkActivityIndicatorManager.m in Sources */, |
807 | E6D8DF3D27A942920006A3A9 /* AFAutoPurgingImageCache.m in Sources */, | 810 | E6D8DF3D27A942920006A3A9 /* AFAutoPurgingImageCache.m in Sources */, |
811 | + E634A362282151E30069DE27 /* StepsView.swift in Sources */, | ||
808 | E6D8DF0A27A942920006A3A9 /* WLAPSItem.m in Sources */, | 812 | E6D8DF0A27A942920006A3A9 /* WLAPSItem.m in Sources */, |
809 | E6D8DF2C27A942920006A3A9 /* UIProgressView+AFNetworking.m in Sources */, | 813 | E6D8DF2C27A942920006A3A9 /* UIProgressView+AFNetworking.m in Sources */, |
810 | E6D8DF3C27A942920006A3A9 /* UIWebView+AFNetworking.m in Sources */, | 814 | E6D8DF3C27A942920006A3A9 /* UIWebView+AFNetworking.m in Sources */, | ... | ... |
No preview for this file type
... | @@ -36,5 +36,37 @@ | ... | @@ -36,5 +36,37 @@ |
36 | landmarkType = "24"> | 36 | landmarkType = "24"> |
37 | </BreakpointContent> | 37 | </BreakpointContent> |
38 | </BreakpointProxy> | 38 | </BreakpointProxy> |
39 | + <BreakpointProxy | ||
40 | + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | ||
41 | + <BreakpointContent | ||
42 | + uuid = "8A4576AC-8F1C-4F2D-A153-7B9F703BDF6D" | ||
43 | + shouldBeEnabled = "Yes" | ||
44 | + ignoreCount = "0" | ||
45 | + continueAfterRunningActions = "No" | ||
46 | + filePath = "WarplySDKFrameworkIOS/StepsView.swift" | ||
47 | + startingColumnNumber = "9223372036854775807" | ||
48 | + endingColumnNumber = "9223372036854775807" | ||
49 | + startingLineNumber = "21" | ||
50 | + endingLineNumber = "21" | ||
51 | + landmarkName = "init()" | ||
52 | + landmarkType = "7"> | ||
53 | + </BreakpointContent> | ||
54 | + </BreakpointProxy> | ||
55 | + <BreakpointProxy | ||
56 | + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | ||
57 | + <BreakpointContent | ||
58 | + uuid = "89C2FADA-F600-4DE9-A167-666EB874685F" | ||
59 | + shouldBeEnabled = "Yes" | ||
60 | + ignoreCount = "0" | ||
61 | + continueAfterRunningActions = "No" | ||
62 | + filePath = "WarplySDKFrameworkIOS/StepsView.swift" | ||
63 | + startingColumnNumber = "9223372036854775807" | ||
64 | + endingColumnNumber = "9223372036854775807" | ||
65 | + startingLineNumber = "96" | ||
66 | + endingLineNumber = "96" | ||
67 | + landmarkName = "getSteps()" | ||
68 | + landmarkType = "7"> | ||
69 | + </BreakpointContent> | ||
70 | + </BreakpointProxy> | ||
39 | </Breakpoints> | 71 | </Breakpoints> |
40 | </Bucket> | 72 | </Bucket> | ... | ... |
... | @@ -8,15 +8,17 @@ | ... | @@ -8,15 +8,17 @@ |
8 | #ifndef MyApi_h | 8 | #ifndef MyApi_h |
9 | #define MyApi_h | 9 | #define MyApi_h |
10 | #import <UIKit/UIKit.h> | 10 | #import <UIKit/UIKit.h> |
11 | +#import <CoreMotion/CoreMotion.h> | ||
11 | @class Warply; | 12 | @class Warply; |
12 | 13 | ||
13 | @interface MyApi : NSObject | 14 | @interface MyApi : NSObject |
14 | 15 | ||
15 | @property (nonatomic, weak) Warply *warply; | 16 | @property (nonatomic, weak) Warply *warply; |
16 | 17 | ||
17 | -+ (void)init:(NSDictionary *)launchOptions uuid:(NSString*)uuid merchantId:(NSString*)merchantId lang:(NSString*)lang; | 18 | +- (void)init:(NSDictionary *)launchOptions uuid:(NSString*)uuid merchantId:(NSString*)merchantId lang:(NSString*)lang; |
18 | - (void) setToStage; | 19 | - (void) setToStage; |
19 | - (void) setLang:(NSString*) lang; | 20 | - (void) setLang:(NSString*) lang; |
21 | +- (void) getSteps:(void(^)(CMPedometerData* stepsData)) completion; | ||
20 | - (UIViewController *) openCoupons:(UIView*) parentView; | 22 | - (UIViewController *) openCoupons:(UIView*) parentView; |
21 | //- (UIViewController *) openCoupon:(UIView*) parentView coupon:(NSDictionary*) coupon; | 23 | //- (UIViewController *) openCoupon:(UIView*) parentView coupon:(NSDictionary*) coupon; |
22 | //- (UIViewController *) openCouponBarcode:(UIView*) parentView coupon:(NSDictionary*) coupon; | 24 | //- (UIViewController *) openCouponBarcode:(UIView*) parentView coupon:(NSDictionary*) coupon; | ... | ... |
... | @@ -9,7 +9,6 @@ | ... | @@ -9,7 +9,6 @@ |
9 | #import "MyApi.h" | 9 | #import "MyApi.h" |
10 | #import "Warply.h" | 10 | #import "Warply.h" |
11 | #import "WLUtils.h" | 11 | #import "WLUtils.h" |
12 | - | ||
13 | #import <WarplySDKFrameworkIOS/WarplySDKFrameworkIOS-Swift.h> | 12 | #import <WarplySDKFrameworkIOS/WarplySDKFrameworkIOS-Swift.h> |
14 | 13 | ||
15 | 14 | ||
... | @@ -19,8 +18,10 @@ NSString *WARP_HOST = @"engage.warp.ly"; | ... | @@ -19,8 +18,10 @@ NSString *WARP_HOST = @"engage.warp.ly"; |
19 | NSString *WARP_ERROR_DOMAIN = @"engage.warp.ly"; | 18 | NSString *WARP_ERROR_DOMAIN = @"engage.warp.ly"; |
20 | NSString *MERCHANT_ID; | 19 | NSString *MERCHANT_ID; |
21 | NSString *LANG; | 20 | NSString *LANG; |
21 | +NSDate *date; | ||
22 | +CMPedometer *pedometer; | ||
22 | 23 | ||
23 | -+ (void)init:(NSDictionary *)launchOptions uuid:(NSString*)uuid merchantId:(NSString*)merchantId lang:(NSString*)lang{ | 24 | +- (void)init:(NSDictionary *)launchOptions uuid:(NSString*)uuid merchantId:(NSString*)merchantId lang:(NSString*)lang{ |
24 | #if (DEBUG == 1) | 25 | #if (DEBUG == 1) |
25 | [Warply launchWithAppUUID:uuid launchOptions:launchOptions]; | 26 | [Warply launchWithAppUUID:uuid launchOptions:launchOptions]; |
26 | #else | 27 | #else |
... | @@ -35,6 +36,51 @@ NSString *LANG; | ... | @@ -35,6 +36,51 @@ NSString *LANG; |
35 | int cacheSizeDisk = 0; // 0MB | 36 | int cacheSizeDisk = 0; // 0MB |
36 | NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"]; | 37 | NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"]; |
37 | [NSURLCache setSharedURLCache:sharedCache]; | 38 | [NSURLCache setSharedURLCache:sharedCache]; |
39 | + | ||
40 | + date = [NSDate date]; | ||
41 | + if ([CMPedometer isStepCountingAvailable]) { | ||
42 | + pedometer = [[CMPedometer alloc] init]; | ||
43 | + [NSTimer scheduledTimerWithTimeInterval:0.5f | ||
44 | + target:self | ||
45 | + selector:@selector(recursiveQuery) | ||
46 | + userInfo:nil | ||
47 | + repeats:YES]; | ||
48 | + } else { | ||
49 | + NSLog(@"Nothing available"); | ||
50 | + | ||
51 | + } | ||
52 | +} | ||
53 | + | ||
54 | +- (void)queryDataFrom:(NSDate *)startDate toDate:(NSDate *)endDate { | ||
55 | + [pedometer queryPedometerDataFromDate:startDate | ||
56 | + toDate:endDate | ||
57 | + withHandler: | ||
58 | + ^(CMPedometerData *pedometerData, NSError *error) { | ||
59 | + | ||
60 | + NSLog(@"data:%@, error:%@", pedometerData, error); | ||
61 | + | ||
62 | + dispatch_async(dispatch_get_main_queue(), ^{ | ||
63 | + if (error) { | ||
64 | + NSLog(@"Error = %@",error.userInfo); | ||
65 | + } else { | ||
66 | + } | ||
67 | + }); | ||
68 | + }]; | ||
69 | +} | ||
70 | + | ||
71 | +- (void)recursiveQuery { | ||
72 | + NSDate *to = [NSDate date]; | ||
73 | + NSDate *from = [to dateByAddingTimeInterval:-(24. * 3600.)]; | ||
74 | + [self queryDataFrom:from toDate:to]; | ||
75 | +} | ||
76 | + | ||
77 | +- (void) getSteps:(void(^)(CMPedometerData* stepsData)) completion { | ||
78 | + [pedometer startPedometerUpdatesFromDate:date | ||
79 | + withHandler:^(CMPedometerData *pedometerData, NSError *error) { | ||
80 | + dispatch_async(dispatch_get_main_queue(), ^{ | ||
81 | + completion(pedometerData); | ||
82 | + }); | ||
83 | + }]; | ||
38 | } | 84 | } |
39 | 85 | ||
40 | - (void) setToStage { | 86 | - (void) setToStage { | ... | ... |
1 | +// | ||
2 | +// StepsView.swift | ||
3 | +// WarplySDKFrameworkIOS | ||
4 | +// | ||
5 | +// Created by Βασιλης Σκουρας on 3/5/22. | ||
6 | +// | ||
7 | + | ||
8 | +#if canImport(SwiftUI) | ||
9 | +import SwiftUI | ||
10 | +import Combine | ||
11 | +import Foundation | ||
12 | +import UIKit | ||
13 | + | ||
14 | +class StepsModel { | ||
15 | + var steps: AnyObject | ||
16 | + | ||
17 | + init() async { //initializer method | ||
18 | + let instanceOfMyApi = MyApi() | ||
19 | + self.steps = await instanceOfMyApi.getSteps { _ in | ||
20 | + } as AnyObject | ||
21 | + print(steps) | ||
22 | + } | ||
23 | + | ||
24 | + var getSteps: AnyObject { | ||
25 | + get { // getter | ||
26 | + return steps | ||
27 | + } | ||
28 | + } | ||
29 | +} | ||
30 | + | ||
31 | +extension StepsView { | ||
32 | + struct headerView: View { | ||
33 | + var goBack: () -> () | ||
34 | + var uiscreen = UIScreen.main.bounds | ||
35 | + | ||
36 | + | ||
37 | + var body: some View { | ||
38 | + HStack(alignment: .center) { | ||
39 | + Button { | ||
40 | + // Button Action | ||
41 | + goBack() | ||
42 | + } label: { | ||
43 | + Image("ic_back", bundle: Bundle(for: MyEmptyClass.self)) | ||
44 | + .resizable() | ||
45 | + .aspectRatio(contentMode: .fit) | ||
46 | + .frame(width: self.uiscreen.height * 0.025, height: self.uiscreen.height * 0.02) | ||
47 | + } | ||
48 | + Spacer().frame(width: 0) | ||
49 | + Text("Όλα τα κουπόνια μου") | ||
50 | + .fontWeight(.medium) | ||
51 | + .font(.system(size: 16)) | ||
52 | + .foregroundColor(Color(red: 0.20784313725490197, green: 0.3176470588235294, blue: 0.40784313725490196)) | ||
53 | + .multilineTextAlignment(.center) | ||
54 | + .frame(maxWidth: .infinity) | ||
55 | + .padding(.horizontal) | ||
56 | + .offset(x: -self.uiscreen.height * 0.0125) | ||
57 | + } | ||
58 | + .frame(maxWidth: .infinity) | ||
59 | + .padding(.horizontal) | ||
60 | + .padding(.vertical, 10) | ||
61 | + } | ||
62 | + } | ||
63 | + | ||
64 | +} | ||
65 | + | ||
66 | +@available(iOS 13.0.0, *) | ||
67 | +struct StepsView: View { | ||
68 | + @State private var steps = "Loading" | ||
69 | + var parentView: UIView | ||
70 | + | ||
71 | + func getSteps() async -> AnyObject { | ||
72 | + return await StepsModel().getSteps | ||
73 | + } | ||
74 | + | ||
75 | + var uiscreen = UIScreen.main.bounds | ||
76 | + | ||
77 | + init(parentView: UIView) { //initializer method | ||
78 | + self.parentView = parentView | ||
79 | + } | ||
80 | + | ||
81 | + func goBack(){ | ||
82 | + for subview in parentView.subviews { | ||
83 | + if(subview.tag == 1) { | ||
84 | + subview.removeFromSuperview() | ||
85 | + } | ||
86 | + } | ||
87 | + } | ||
88 | + | ||
89 | + func getSteps() async -> String { | ||
90 | + let instanceOfMyApi = MyApi() | ||
91 | + let stepsData = await instanceOfMyApi.getSteps { _ in | ||
92 | + } as AnyObject | ||
93 | +// DispatchQueue.main.async { | ||
94 | +// steps = "" | ||
95 | +// } | ||
96 | + return "" | ||
97 | + } | ||
98 | + | ||
99 | + var body: some View { | ||
100 | + VStack { | ||
101 | + headerView(goBack: goBack) | ||
102 | + Text(steps) | ||
103 | + .onAppear { | ||
104 | + async { | ||
105 | + let instanceOfMyApi = MyApi() | ||
106 | + let stepsData = try? await instanceOfMyApi.getSteps { _ in | ||
107 | + } as AnyObject | ||
108 | + self.steps = "" | ||
109 | + } | ||
110 | + } | ||
111 | + | ||
112 | + } | ||
113 | + .frame(maxWidth: .infinity, maxHeight: .infinity ) | ||
114 | +// .frame(width:self.uiscreen.width, height:self.uiscreen.height ) | ||
115 | + } | ||
116 | +} | ||
117 | +#endif | ||
118 | + | ||
119 | +//@available(iOS 13.0.0, *) | ||
120 | +//struct Previews_CouponsView_Previews: PreviewProvider { | ||
121 | +// static var uiscreen = UIScreen.main.bounds | ||
122 | +// static var previews: some View { | ||
123 | +// ZStack { | ||
124 | +// Image("ic_back", bundle: Bundle(for: MyEmptyClass.self)) | ||
125 | +// .resizable() | ||
126 | +// .frame(width: self.uiscreen.height * 0.025, height: self.uiscreen.height * 0.02) | ||
127 | +// .offset(x: -self.uiscreen.width / 2 + self.uiscreen.width * 0.05, y: self.uiscreen.height * 0.07) | ||
128 | +// Text("Όλα τα κουπόνια μου") | ||
129 | +// .frame(width: self.uiscreen.width * 0.8, height: self.uiscreen.height * 0.025, alignment: .center) | ||
130 | +// .offset( y: self.uiscreen.height * 0.07) | ||
131 | +// } | ||
132 | +// | ||
133 | +// } | ||
134 | +//} | ||
135 | + |
... | @@ -365,4 +365,8 @@ public class swiftApi { | ... | @@ -365,4 +365,8 @@ public class swiftApi { |
365 | public func openCouponBarcode(parent: UIView, coupon: CouponItemModel) -> UIViewController { | 365 | public func openCouponBarcode(parent: UIView, coupon: CouponItemModel) -> UIViewController { |
366 | return UIHostingController(rootView: CouponBarcodeView(parentView: parent, coupon: coupon)) | 366 | return UIHostingController(rootView: CouponBarcodeView(parentView: parent, coupon: coupon)) |
367 | } | 367 | } |
368 | + | ||
369 | + public func openSteps(parent: UIView) -> UIViewController { | ||
370 | + return UIHostingController(rootView: StepsView(parentView: parent)) | ||
371 | + } | ||
368 | } | 372 | } | ... | ... |
-
Please register or login to post a comment