From 46acca18a3d1744e1930f0bac7509a2a5959df1b Mon Sep 17 00:00:00 2001 From: 无故事王国 <841720330@qq.com> Date: 星期三, 26 六月 2024 18:58:14 +0800 Subject: [PATCH] fix --- DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen.png | 0 DolphinEnglishLearnStudent/Base.lproj/LaunchScreen.storyboard | 32 ++ DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift | 29 +- DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift | 42 +++ DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift | 23 + DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift | 50 ++++ DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.swift | 20 + DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift | 12 DolphinEnglishLearnStudent/Moudle/Market/VC/MarketExchangeVC.swift | 8 DolphinEnglishLearnStudent/Moudle/Home/HomeVC.swift | 26 - DolphinEnglishLearnStudent/Assets.xcassets/.DS_Store | 0 DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/Contents.json | 22 ++ DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift | 23 ++ DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.xib | 8 DolphinEnglishLearnStudent/Other/UIView/VoiceHandleView.swift | 9 DolphinEnglishLearnStudent/SceneDelegate.swift | 17 + DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift | 37 ++ DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_1_VC.swift | 6 DolphinEnglishLearnStudent/Moudle/Home/Listen/View/ChooseLevelView.swift | 6 DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift | 17 + DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen@2x.png | 0 DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift | 21 + DolphinEnglishLearnStudent/Other/UIView/CommonAlertView.swift | 24 ++ DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_2_VC.swift | 2 DolphinEnglishLearnStudent/Models/CommonModel.swift | 14 + DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.swift | 2 DolphinEnglishLearnStudent/AppDelegate.swift | 2 DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.xib | 3 DolphinEnglishLearnStudent.xcodeproj/project.pbxproj | 4 DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift | 6 DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift | 79 ++++++- DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.xib | 8 DolphinEnglishLearnStudent/Other/UIView/StudyHandleView.xib | 12 + 33 files changed, 444 insertions(+), 120 deletions(-) diff --git a/DolphinEnglishLearnStudent.xcodeproj/project.pbxproj b/DolphinEnglishLearnStudent.xcodeproj/project.pbxproj index 2cda374..20ad1fe 100644 --- a/DolphinEnglishLearnStudent.xcodeproj/project.pbxproj +++ b/DolphinEnglishLearnStudent.xcodeproj/project.pbxproj @@ -990,7 +990,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = DolphinEnglishLearnStudent/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "海豚英语"; + INFOPLIST_KEY_CFBundleDisplayName = "海豚英语-学习端"; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; @@ -1125,7 +1125,7 @@ ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = DolphinEnglishLearnStudent/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "海豚英语"; + INFOPLIST_KEY_CFBundleDisplayName = "海豚英语-学习端"; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; diff --git a/DolphinEnglishLearnStudent/AppDelegate.swift b/DolphinEnglishLearnStudent/AppDelegate.swift index 2c05047..eeb9137 100644 --- a/DolphinEnglishLearnStudent/AppDelegate.swift +++ b/DolphinEnglishLearnStudent/AppDelegate.swift @@ -15,7 +15,7 @@ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. - + sleep(2) if WXApi.isWXAppInstalled(){ WXApi.registerApp(WeChatAPPID, universalLink: "https://dollearn/app/") } diff --git a/DolphinEnglishLearnStudent/Assets.xcassets/.DS_Store b/DolphinEnglishLearnStudent/Assets.xcassets/.DS_Store new file mode 100644 index 0000000..126f78c --- /dev/null +++ b/DolphinEnglishLearnStudent/Assets.xcassets/.DS_Store Binary files differ diff --git a/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/Contents.json b/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/Contents.json new file mode 100644 index 0000000..4b0ff48 --- /dev/null +++ b/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "launchscreen.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "launchscreen@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen.png b/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen.png new file mode 100644 index 0000000..4e2d4b3 --- /dev/null +++ b/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen.png Binary files differ diff --git a/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen@2x.png b/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen@2x.png new file mode 100644 index 0000000..10417bb --- /dev/null +++ b/DolphinEnglishLearnStudent/Assets.xcassets/launchscreen 1.imageset/launchscreen@2x.png Binary files differ diff --git a/DolphinEnglishLearnStudent/Base.lproj/LaunchScreen.storyboard b/DolphinEnglishLearnStudent/Base.lproj/LaunchScreen.storyboard index 865e932..1956801 100644 --- a/DolphinEnglishLearnStudent/Base.lproj/LaunchScreen.storyboard +++ b/DolphinEnglishLearnStudent/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,11 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> + <device id="ipad10_9rounded" orientation="landscape" layout="fullscreen" appearance="light"/> <dependencies> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> @@ -11,15 +14,32 @@ <objects> <viewController id="01J-lp-oVM" sceneMemberID="viewController"> <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> - <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <rect key="frame" x="0.0" y="0.0" width="1180" height="820"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launchscreen 1" translatesAutoresizingMaskIntoConstraints="NO" id="ehh-vH-WKP"> + <rect key="frame" x="0.0" y="0.0" width="1180" height="820"/> + </imageView> + </subviews> <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <constraints> + <constraint firstItem="ehh-vH-WKP" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="Ybg-4L-fSp"/> + <constraint firstAttribute="bottom" secondItem="ehh-vH-WKP" secondAttribute="bottom" id="gd4-Si-weW"/> + <constraint firstItem="ehh-vH-WKP" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="qBO-Ri-etD"/> + <constraint firstItem="ehh-vH-WKP" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="uuP-YQ-Zyd"/> + </constraints> </view> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="53" y="375"/> + <point key="canvasLocation" x="52.881355932203391" y="374.63414634146341"/> </scene> </scenes> + <resources> + <image name="launchscreen 1" width="1080" height="810"/> + <systemColor name="systemBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> + </resources> </document> diff --git a/DolphinEnglishLearnStudent/Models/CommonModel.swift b/DolphinEnglishLearnStudent/Models/CommonModel.swift index 8e85247..195a981 100644 --- a/DolphinEnglishLearnStudent/Models/CommonModel.swift +++ b/DolphinEnglishLearnStudent/Models/CommonModel.swift @@ -288,6 +288,9 @@ var count = 0 var lookIntegral = 0 + //custom + var playNow:Bool = false //立刻播放 + } class Listen1SubModel:HandyJSON,Hashable{ @@ -327,6 +330,9 @@ //游戏类型2专用 var isOpen:Bool = false + + // 自主学习3专用 (是否已回答) + var isAnster:Bool = false } @available(*,deprecated,message: "废弃") @@ -352,7 +358,9 @@ var week: Int = 0 } -struct StudyScheduleModel:HandyJSON{ +struct StudyScheduleModel:HandyJSON,Hashable{ + init() {} + var answer: Int = 0 var day: Int = 0 var computeSchedule:Int = 0 @@ -369,6 +377,10 @@ var week: Int = 0 var weekStudy: Int = 0 var gameDifficulty:Int = 0 + + var hashValue: Int{ + return answer+day+computeSchedule+induction+listen+look+monthStudy+pair+todayStudy+totalStudy+week+weekStudy+gameDifficulty + } } class SimpleListenDataModel:HandyJSON,Hashable{ diff --git a/DolphinEnglishLearnStudent/Moudle/Home/HomeVC.swift b/DolphinEnglishLearnStudent/Moudle/Home/HomeVC.swift index cd17a38..7161f0d 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/HomeVC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/HomeVC.swift @@ -14,10 +14,15 @@ super.viewDidLoad() Services.parentPage().subscribe(onNext: {data in - if let img = data.data{ - SDWebImageDownloader.shared.downloadImage(with: URL(string: img)) { image, _, _, _ in - if let img = image{ - LaunchImageHelper.changeAllLaunchImageToLandscape(img) + if let imgStr = data.data{ + let promptlaunchScreen = UserDefaults.standard.object(forKey: "promptlaunchScreen") as? String + if promptlaunchScreen != imgStr || promptlaunchScreen == nil{ + SDWebImageDownloader.shared.downloadImage(with: URL(string: imgStr)) { image, _, _, _ in + if let img = image{ + LaunchImageHelper.changeAllLaunchImageToLandscape(img) + UserDefaults.standard.setValue(imgStr, forKey: "promptlaunchScreen") + UserDefaults.standard.synchronize() + } } } } @@ -25,23 +30,10 @@ Services.promptVoice().subscribe(onNext: {data in if let model = data.data{ -// ArchiveTool.archive(model: model,force: true) -// -// if let v = ArchiveTool.unarchive(model: PromptVoiceModel.self){ -// -// } - let voice = UserDefaults.standard.object(forKey: "promptVoiceDate") as? String if model.updateTime != voice{ VoicePlayer.share().donwloadPromoteVoice(successVoice: model.correct, failVoice: model.error,updateTime: model.updateTime) } - } - }).disposed(by: disposeBag) - - Services.onlineDuration().subscribe(onNext: { data in - if let time = data.data{ - sceneDelegate?.globalTimeval = time - sceneDelegate?.startTimer() } }).disposed(by: disposeBag) } diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift index c32c886..55f77ba 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift @@ -43,6 +43,12 @@ self.img_state.alpha = 1 self.img_state.transform = .init(scaleX: 1, y: 1) } + DispatchQueue.main.asyncAfter(deadline: .now()+3) { + UIView.animate(withDuration: 0.6) { + self.img_state.alpha = 0 + self.img_state.transform = .init(scaleX: 0.1, y: 0.1) + } + } case .none: img_state.alpha = 0 img_state.transform = .init(scaleX: 0.1, y: 0.1) diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift index 9407dea..f5607ec 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift @@ -32,6 +32,9 @@ let img1 = UIImageView(image: UIImage(named: "icon_play_1")!.withTintColor(UIColor(hexString: "#41A2EB")!)) let img2 = UIImageView(image: UIImage(named: "icon_playing")!.withTintColor(UIColor(hexString: "#41A2EB")!)) + + let stateImg = UIImageView() + let playBtn = UIButton(type: .custom) private var model:SimpleListenDataModel! @@ -91,6 +94,13 @@ make.width.height.equalTo(32) make.centerY.equalToSuperview() } + + addSubview(stateImg) + stateImg.snp.makeConstraints { make in + make.center.equalToSuperview() + make.width.height.equalTo(76) + } + cellResotePay() } @@ -106,6 +116,34 @@ img1.isHidden = true playBtn.isHidden = true playIndexClouse?(indexPath) + } + + func setState(success:Bool){ + if success{ + stateImg.image = UIImage(named: "icon_success") + }else{ + stateImg.image = UIImage(named: "icon_fail") + } + + + stateImg.alpha = 0 + stateImg.transform = .init(scaleX: 0.1, y: 0.1) + layoutIfNeeded() + + UIView.animate(withDuration: 0.4) { + self.stateImg.alpha = 1 + self.stateImg.transform = .init(scaleX: 1.0, y: 1.0) + } completion: { state in + if state{ + DispatchQueue.main.asyncAfter(wallDeadline: .now()+3){ + UIView.animate(withDuration: 0.5) { + self.stateImg.alpha = 0 + self.stateImg.transform = .init(scaleX: 0.1, y: 0.1) + } + } + } + } + } func cellPayatIndex(_ clouse:@escaping (IndexPath)->Void){ @@ -131,17 +169,21 @@ fatalError("init(coder:) has not been implemented") } - @objc func toFromAction(_ superView:UIView? = nil){ + func toFromAction(_ superView:UIView? = nil,c:Bool? = nil){ superView?.isUserInteractionEnabled = false UIView.transition(from: mask_img, to: answer_img, duration: 0.6, options: [.transitionFlipFromLeft,.showHideTransitionViews]) { _ in - superView?.isUserInteractionEnabled = true + if c == true{ + superView?.isUserInteractionEnabled = true + } } } - @objc func toBackAction(_ superView:UIView? = nil){ + func toBackAction(_ superView:UIView? = nil,c:Bool? = nil){ superView?.isUserInteractionEnabled = false UIView.transition(from: answer_img, to: mask_img, duration: 0.6,options: [.transitionFlipFromRight,.showHideTransitionViews]){ _ in - superView?.isUserInteractionEnabled = true + if c == true{ + superView?.isUserInteractionEnabled = true + } } } } diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift index a075c81..fe7ae6a 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.swift @@ -16,15 +16,18 @@ @IBOutlet weak var btn_playing: UIButton! @IBOutlet weak var view_playHandle: UIView! @IBOutlet weak var img_playing: UIImageView! + @IBOutlet weak var img_playSuccess: UIImageView! private var model:Listen1SubModel! private var playAtClouse:((IndexPath)->Void)? var indexPath:IndexPath! - override func awakeFromNib() { super.awakeFromNib() +// img_playSuccess.alpha = 0 +// img_playSuccess.transform = .init(scaleX: 0.1, y: 0.1) view_container.jq_addShadows(shadowColor: .black.withAlphaComponent(0.31), corner: 8, radius: 3, offset: CGSize(width: 0, height: 1), opacity: 1) + layoutIfNeeded() } func setModel(_ model:Listen1SubModel,isplaying:Bool){ @@ -40,9 +43,27 @@ func canClick(_ state:Bool){ btn_play.isEnabled = state +// view_playHandle.alpha = state == true ? 1:0 view_playHandle.backgroundColor = state == true ? UIColor(hexString: "#41A2EB") : .gray } + func isPlaying(isplaying:Bool){ + btn_play.alpha = (isplaying ? 0:1) + btn_playing.alpha = (isplaying ? 0:1) + img_playing.alpha = (isplaying ? 1:0) + } + +// func playSuccess(){ +// UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.4, options: .layoutSubviews) { +// self.img_playSuccess.alpha = 1 +// self.img_playSuccess.transform = .init(scaleX: 1, y: 1) +// } +// UIView.animate(withDuration: 0.5, delay: 3.0) { +// self.img_playSuccess.alpha = 0 +// self.img_playSuccess.transform = .init(scaleX: 0.1, y: 0.1) +// } +// } + @IBAction func playAction(_ sender: Any) { playAtClouse?(indexPath) diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.xib b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.xib index e73fe3f..aeea522 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.xib +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_3_CCell.xib @@ -18,7 +18,7 @@ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vtr-2e-B5C"> - <rect key="frame" x="0.0" y="33" width="159" height="52"/> + <rect key="frame" x="0.0" y="0.0" width="159" height="52"/> <subviews> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7yc-PU-RgV"> <rect key="frame" x="104" y="10" width="32" height="32"/> @@ -56,10 +56,10 @@ </userDefinedRuntimeAttributes> </view> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qxz-6s-e5b"> - <rect key="frame" x="0.0" y="110" width="630" height="434"/> + <rect key="frame" x="0.0" y="77" width="630" height="467"/> <subviews> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="n5n-eb-5xI"> - <rect key="frame" x="5" y="5" width="620" height="424"/> + <rect key="frame" x="5" y="5" width="620" height="457"/> <color key="backgroundColor" red="0.94509803921568625" green="0.94509803921568625" blue="0.94509803921568625" alpha="0.84999999999999998" colorSpace="custom" customColorSpace="sRGB"/> </imageView> </subviews> @@ -78,7 +78,7 @@ <constraint firstItem="qxz-6s-e5b" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="SLN-pI-I4q"/> <constraint firstItem="vtr-2e-B5C" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="enY-sX-Oib"/> <constraint firstItem="qxz-6s-e5b" firstAttribute="top" secondItem="vtr-2e-B5C" secondAttribute="bottom" constant="25" id="iLs-4C-NaW"/> - <constraint firstItem="vtr-2e-B5C" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="33" id="jbw-ZJ-YrV"/> + <constraint firstItem="vtr-2e-B5C" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="jbw-ZJ-YrV"/> <constraint firstAttribute="bottom" secondItem="qxz-6s-e5b" secondAttribute="bottom" constant="10" id="msT-T9-1c4"/> </constraints> <size key="customSize" width="630" height="554"/> diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.xib b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.xib index fccf83c..4d196dc 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.xib +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_lesson_4_CCell.xib @@ -59,14 +59,14 @@ </userDefinedRuntimeAttributes> </view> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OJ6-0b-fVC"> - <rect key="frame" x="0.0" y="77" width="597" height="423"/> + <rect key="frame" x="0.0" y="68" width="597" height="432"/> <subviews> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="XW5-ds-CXG"> - <rect key="frame" x="5" y="5" width="587" height="413"/> + <rect key="frame" x="5" y="5" width="587" height="422"/> <color key="backgroundColor" red="0.94509803920000002" green="0.94509803920000002" blue="0.94509803920000002" alpha="0.84999999999999998" colorSpace="custom" customColorSpace="sRGB"/> </imageView> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_success" translatesAutoresizingMaskIntoConstraints="NO" id="eyJ-Qy-E0w"> - <rect key="frame" x="258.5" y="171" width="80" height="81"/> + <rect key="frame" x="258.5" y="175.5" width="80" height="81"/> </imageView> </subviews> <color key="backgroundColor" systemColor="systemBackgroundColor"/> @@ -87,7 +87,7 @@ <constraint firstItem="Xjz-V8-keG" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="5Iq-AY-uUK"/> <constraint firstItem="OJ6-0b-fVC" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="6p8-30-BD6"/> <constraint firstAttribute="trailing" secondItem="OJ6-0b-fVC" secondAttribute="trailing" id="EAu-4C-peY"/> - <constraint firstItem="OJ6-0b-fVC" firstAttribute="top" secondItem="Xjz-V8-keG" secondAttribute="bottom" constant="25" id="YpO-u8-Uyg"/> + <constraint firstItem="OJ6-0b-fVC" firstAttribute="top" secondItem="Xjz-V8-keG" secondAttribute="bottom" constant="16" id="YpO-u8-Uyg"/> <constraint firstAttribute="bottom" secondItem="OJ6-0b-fVC" secondAttribute="bottom" constant="10" id="m6e-nJ-ukf"/> </constraints> <size key="customSize" width="597" height="510"/> diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift index 2c0cf22..2cd5e7d 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFightVC.swift @@ -78,7 +78,7 @@ } } - //所有回答的 + //所有回答的 两游戏在用 var answerItems = Dictionary<Int,Any>() //{page:0,data:String,currectAt:0} var answerCount = BehaviorRelay<Int>(value: 1) @@ -167,7 +167,12 @@ required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + sceneDelegate?.suspendTimer() + } + override func viewDidLoad() { super.viewDidLoad() @@ -216,6 +221,7 @@ GameBeginTipView.show { if let data = result.data{ weakSelf.data = data + (weakSelf.data as! Listen1Model).data?.playNow = true weakSelf.pageVC.reloadData() } } @@ -315,9 +321,9 @@ private func setPages(){ switch viewModel.listenType.value{ - case .lesson1,.lesson2,.lesson5: + case .lesson1,.lesson5: label_pageNum.text = "已完成:\(viewModel.answerCount.value)/\((data as! ListenNewModel).subjectList.flatMap({$0}).count)" - case .lesson3: + case .lesson2,.lesson3: label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\((data as! ListenNewModel).subjectList.count)" case .lesson4: //两题为一组:需要/2 @@ -333,6 +339,13 @@ let count = (data as! Listen1Model).storyList.count viewModel.maxPage.accept(count) label_pageNum.text = "已完成:\(viewModel.currentPage.value + 1)/\(count)" + + if viewModel.listenType.value == .story2{ + btn_next.isHidden = (viewModel.currentPage.value + 1) == viewModel.maxPage.value + if btn_next.isHidden{ + btn_exit.setTitle("完成", for: .normal) + } + } } } @@ -369,13 +382,26 @@ private func gamesComplete(gameId:Int,integral:Int){ var name = "" + var accuracy:Int = 0 + var totalNum:Double = 0 + var toalIntegral:Int = 0 + if viewModel.listenType.value == .game1{ name = "超级听力" + totalNum = Double(viewModel.correctNum + viewModel.errorNum) + if totalNum > 0{ + accuracy = Int(Double(viewModel.correctNum) / totalNum * 100) + } + toalIntegral = floor(Double(integral) * (Double(accuracy) / 100.0)).int }else{ name = "超级记忆" + let v = viewModel.answerItems.first?.value as! Listen1Model + totalNum = Double(v.photoList.count) + if totalNum > 0{ + accuracy = Int(Double(viewModel.correctNum) / Double(viewModel.correctNum + viewModel.errorNum) * 100) + } + toalIntegral = floor(Double(integral) * (Double(accuracy) / 100.0)).int } - - let accuracy = Int(Double(viewModel.correctNum) / Double(viewModel.correctNum + viewModel.errorNum) * 100) Services.completeGames(gameId: gameId, gameName: name, difficulty: viewModel.gameLevel.value, accuracy: accuracy, useTime: viewModel.times).subscribe(onNext: {data in NotificationCenter.default.post(name: Refresh_ListenSchedule_Noti, object: nil) @@ -383,7 +409,7 @@ timer.invalidate() - let vc = HomeStudyCompleteVC(correctNum: viewModel.correctNum, errorNum: viewModel.errorNum, totalCoin: integral, listenType: viewModel.listenType.value) + let vc = HomeStudyCompleteVC(correctNum: viewModel.correctNum, errorNum: viewModel.errorNum, totalCoin: toalIntegral, listenType: viewModel.listenType.value,totalNum:totalNum.int) vc.title = viewModel.listenType.value.rawTitle push(vc: vc) } @@ -407,7 +433,7 @@ if btn_exit.titleLabel?.text == "完成"{ if viewModel.listenType.value == .story2{ let v = data as! Listen1Model - let accuracy = Int(Double(viewModel.correctNum) / Double(viewModel.correctNum + viewModel.errorNum) * 100) + let accuracy = 100 storyComplete(storyId: v.data!.id, accuracy: accuracy, studyTime: viewModel.times, type: 1, integral: v.data!.lookIntegral) } }else{ diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift index 6e0cb04..83d0d92 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_2_VC.swift @@ -129,8 +129,6 @@ private func addStackView(){ -// getNextAnswer() - for subV in stackView.arrangedSubviews{ subV.removeFromSuperview() } @@ -179,12 +177,19 @@ weakSelf.rootViewModel.insertCorrectAnswer(teamId: teamId, answerId: answerId) }else{ lessionType = .fail + // 重置按钮至最初样式 + weakSelf.playedIndex.removeAll() + for sub in weakSelf.stackView.arrangedSubviews as! [StudyHandleView]{ + sub.btn_pay.isEnabled = true + sub.btn_choose.isEnabled = true + sub.resetView() + sub.view_choose.alpha = 0 + } weakSelf.voicePlayer.playFailVoice() } switch lessionType { case .success: -// weakSelf.isAnsterComplete = true weakSelf.rootViewModel.correctNum += 1 handleView.btn_choose.isEnabled = false handleView.btn_state.setImage(UIImage(named: "icon_success_small"), for: .normal) @@ -269,7 +274,6 @@ playedIndex.removeAll() let newRow = viewModel.selectIndex.value!.row+1 if newRow >= listenNewModel.subjectList[page].count{ //防止坐标越界 -// rootViewModel.answerItems[page] = listenNewModel.subjectList[page] NotificationCenter.default.post(name: NextLession_Noti, object: nil);return } diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift index defdd6f..b89b87f 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_3_VC.swift @@ -67,6 +67,9 @@ super.viewDidLoad() navigationItem.titleView = UIView() playIndex.insert(IndexPath(row: 0, section: 0)) + listenNewModel.subjectList[page][0].isQuestion = 1 + listenNewModel.subjectList[page][1].isQuestion = 1 + listenNewModel.subjectList[page][3].isQuestion = 1 } func restore(){ @@ -87,6 +90,7 @@ collectionView.delegate = self collectionView.dataSource = self collectionView.showsVerticalScrollIndicator = false + collectionView.contentInset = UIEdgeInsets(top: 33, left: 0, bottom: 0, right: 0) collectionView.backgroundColor = .clear view.addSubview(collectionView) } @@ -122,10 +126,7 @@ v.removeFromSuperview() } - - if isPlayingIndex == IndexPath(row: 2, section: 0) || isPlayingIndex == IndexPath(row: 1, section: 1) || isPlayingIndex == IndexPath(row: 2, section: 1) || !force{ var tempImageArray = [String]() - tempImageArray.append(listenNewModel.subjectList[page][2].img) tempImageArray.append(listenNewModel.subjectList[page][4].img) tempImageArray.append(listenNewModel.subjectList[page][5].img) @@ -133,7 +134,7 @@ view.addSubview(stackView) stackView.snp.makeConstraints { make in make.right.equalToSuperview().offset(-82) - make.centerY.equalToSuperview() + make.centerY.equalToSuperview().offset(10) make.height.equalTo(52) } @@ -160,7 +161,6 @@ } tempAnswerViews.shuffle() stackView.addArrangedSubviews(tempAnswerViews) - } } @objc private func chooseAnswerAction(btn:UIButton){ @@ -171,9 +171,9 @@ alertError(msg: "请先听题");return } - if isPlayingIndex != nil { - alertError(msg: "请先听题");return - } +// if isPlayingIndex != nil { +// alertError(msg: "请先听题");return +// } if answterCount == 0 && !playIndex.contains(IndexPath(row: 2, section: 0)){ alertError(msg: "请先听题");return @@ -206,7 +206,9 @@ } if subV?.imageUrl == listenNewModel.subjectList[page][valueIndex].img{ + listenNewModel.subjectList[page][valueIndex].isAnster = true answerType = .success + subV?.alpha = 0 voicePlayer.playSuccessVoice() }else{ answerType = .fail @@ -241,24 +243,52 @@ } guard ansterIndePath != nil else {return} - self.viewModel.selectIndex.accept(nil) if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_lesson_3_CCell", for: ansterIndePath!) as? ListenFight_lesson_3_CCell{ var newFrame = cell.img_cover.convert(cell.img_cover.bounds, to: self.view) newFrame.origin.x += 0 newFrame.origin.y += 0 + + let successImage = UIImageView(image: UIImage(named: "icon_success")) + successImage.bounds = CGRect(x: 0, y: 0, width: 75, height: 75) + successImage.center = newFrame.center + successImage.transform = .init(scaleX: 0.1, y: 0.1) + successImage.alpha = 0 + successImage.layoutIfNeeded() + self.view.addSubview(successImage) + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.4) { + successImage.transform = .init(scaleX: 1.0, y: 1.0) + successImage.alpha = 1 + } + + UIView.animate(withDuration: 0.5, delay: 3) { + successImage.transform = .init(scaleX: 0.1, y: 0.1) + successImage.alpha = 0 + }completion: { _ in + successImage.removeFromSuperview() + } + UIView.animate(withDuration: 0.4) { copyView?.frame = newFrame } completion: { _ in self.answterCount += 1 + + let cell = self.collectionView.cellForItem(at: self.viewModel.selectIndex.value!) as! ListenFight_lesson_3_CCell + self.isPlayingIndex = self.viewModel.selectIndex.value + cell.isPlaying(isplaying: true) + self.voicePlayer.playerAt(url: self.listenNewModel.subjectList[self.page][valueIndex].correct) let teamId = self.listenNewModel.data?.id.components(separatedBy: ",")[self.page] let answerId = self.listenNewModel.subjectList[self.page][valueIndex].id self.rootViewModel.insertCorrectAnswer(teamId: teamId, answerId: answerId) + for v in self.stackView.arrangedSubviews{ + v.removeFromSuperview() + } + DispatchQueue.main.asyncAfter(deadline: .now()+1.0) { - self.setAnswerStackView() + self.viewModel.selectIndex.accept(nil) let v = self.rootViewModel.answerCount.value + 1 self.rootViewModel.answerCount.accept(v) self.collectionView.reloadData() @@ -274,7 +304,10 @@ subV?.btn_fullscreen.alpha = 0 }completion: { _ in DispatchQueue.main.asyncAfter(deadline: .now()+1.5) { - self.setAnswerStackView(force: true) + self.islisten = false + for v in self.stackView.arrangedSubviews{ + v.removeFromSuperview() + } } } default:break @@ -331,7 +364,7 @@ if section == 0{ return CGSize.zero } - return CGSizeMake(JQ_ScreenW, 100) + return CGSizeMake(JQ_ScreenW, 65) } } @@ -344,7 +377,9 @@ cell.canClick(playIndex.contains(indexPath)) cell.palyVoiceAt {[weak self] index in guard let weakSelf = self else { return } + weakSelf.isPlayingIndex = index + weakSelf.viewModel.selectIndex.accept(index) weakSelf.voicePlayer.playerEnd() @@ -354,9 +389,23 @@ weakSelf.voicePlayer.playerAt(url: weakSelf.listenNewModel.subjectList[weakSelf.page][indexPath.row].correct) } - weakSelf.viewModel.selectIndex.accept(index) - //点击答案,就显示 - weakSelf.setAnswerStackView() + + if index == IndexPath(row: 2, section: 0) || index == IndexPath(row: 1, section: 1) || index == IndexPath(row: 2, section: 1){ + + var model:Listen1SubModel? + if indexPath.section == 0{ + model = weakSelf.listenNewModel.subjectList[weakSelf.page][indexPath.row] + } + + if indexPath.section == 1{ + model = weakSelf.listenNewModel.subjectList[weakSelf.page][indexPath.row + 3] + } + + if model?.isAnster == false{ + //点击答案,就显示 + weakSelf.setAnswerStackView() + } + } collectionView.reloadItems(at: [index]) } diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift index 2f372bb..9fb1125 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenFight_lesson_4_VC.swift @@ -216,8 +216,16 @@ answerType = .success voicePlayer.playSuccessVoice() - let teamId = self.listenNewModel.data?.id.components(separatedBy: ",")[self.page] - let answerId = answerModel!.id + var teamId:String = "" + var answerId:Int = 0 + if self.viewModel.selectIndex.value?.section == 1{ + teamId = self.listenNewModel.data?.id.components(separatedBy: ",")[self.page + 1] ?? "" + answerId = answerModel!.id + }else{ + teamId = self.listenNewModel.data?.id.components(separatedBy: ",")[self.page] ?? "" + answerId = answerModel!.id + } + self.rootViewModel.insertCorrectAnswer(teamId: teamId, answerId: answerId) DispatchQueue.main.asyncAfter(deadline: .now()+2) { @@ -278,8 +286,13 @@ UIView.animate(withDuration: 0.4) { tempSubV?.img_state.alpha = 1 }completion: { _ in - DispatchQueue.main.asyncAfter(deadline: .now()+3) { -// self.setAnswerStackView() + + UIView.animate(withDuration: 0.4, delay: 3.0) { + tempSubV?.img_state.alpha = 0 + } + + DispatchQueue.main.asyncAfter(deadline: .now()+3.2) { + self.setAnswerStackView() } } case .none: diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift index 5473cd9..ccfa49c 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift @@ -89,6 +89,7 @@ override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) timer?.invalidate() + timer = nil voicePlayer.delegate = nil voicePlayer.playerInterrupt() } @@ -108,12 +109,16 @@ print("--->开始答题:剩余:\(answerSet.count)") - DispatchQueue.main.asyncAfter(deadline: .now()+3) { + if listen1Model.data?.playNow == true{ self.currentAnswer = self.answerSet.randomElement() //随机 if self.timer == nil{self.startTimer()} + }else{ + DispatchQueue.main.asyncAfter(deadline: .now()+3) { + self.currentAnswer = self.answerSet.randomElement() //随机 + if self.timer == nil{self.startTimer()} + } } } - } override func setUI() { @@ -175,7 +180,7 @@ timer = Timer(timeInterval: 1.0, target: self, selector: #selector(runloopTime), userInfo: nil, repeats: true) } timer?.fire() - RunLoop.current.add(timer!, forMode: .default) + RunLoop.current.add(timer!, forMode: .common) } @objc private func runloopTime(){ @@ -232,22 +237,24 @@ copyView.frame = CGRect(x: x, y: y, width: layout.itemSize.width - 10, height: 40) } completion: { _ in DispatchQueue.main.asyncAfter(deadline: .now()+0.5) { -// self.collectionView.reloadData() self.voicePlayer.playerAt(url: self.currentAnswer?.correct) self.timer?.fireDate = .distantFuture - //答题完成 -// if self.answerSet.count == 0{ -// self.completeQuestion() -// } } } } case .fail: rootViewModel.errorNum += 1 + totalCount += 1 + label_class.text = "\(totalCount)" viewModel.answerType.accept(.fail) + //移除当前题目 + if let c = currentAnswer{ + answerSet.remove(c) + } collectionView.reloadData() DispatchQueue.main.asyncAfter(deadline: .now()+3) { + self.times = self.listen1Model?.data?.time ?? 10 self.currentAnswer = self.answerSet.randomElement() } case .none: diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift index a070c70..2743be3 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift @@ -48,7 +48,7 @@ }() private var timer:Timer? - private var times:Int = 600 + private var times:Int = 120 private var voicePlayer = VoicePlayer.share() required init(listen1Model:Listen1Model){ @@ -62,6 +62,7 @@ for v in listen1Model.voiceList{ v.type = 2 // 音频标识 } + times = listen1Model.data?.answerTime ?? 120 datas.append(contentsOf: listen1Model.photoList) datas.append(contentsOf: listen1Model.voiceList) @@ -107,7 +108,7 @@ view.addSubview(label_time) label_time.snp.makeConstraints { make in - make.left.equalTo(label_surplusTitle.snp.right).offset(0) + make.left.equalTo(label_surplusTitle.snp.right).offset(5) make.centerY.equalTo(label_surplusTitle) make.height.equalTo(44) } @@ -133,7 +134,7 @@ timer = Timer(timeInterval: 1.0, target: self, selector: #selector(runloopTime), userInfo: nil, repeats: true) } timer?.fire() - RunLoop.current.add(timer!, forMode: .default) + RunLoop.current.add(timer!, forMode: .common) } @objc private func runloopTime(){ @@ -143,8 +144,10 @@ if times == 0{ timer?.fireDate = .distantFuture DispatchQueue.main.asyncAfter(deadline: .now()+3) { - self.times = 10 - self.timer?.fireDate = .distantPast + CommonAlertView.showSimple(content: "答题时间已结束,停止作答", completeTitle: "查看成绩") { + self.rootViewModel.answerItems[0] = self.listen1Model + NotificationCenter.default.post(name: NextLession_Noti, object: ["gameId":self.listen1Model.data!.id,"gameIntegral":self.listen1Model.data!.answerIntegral]) + } } } } @@ -164,10 +167,19 @@ lastM?.model.isOpen = true selectModels.removeAll() print("相同") + self.rootViewModel.insertCorrectAnswer(teamId: "\(listen1Model.data!.id)", answerId: firstM!.model.id) viewModel.answerType.accept(.success) rootViewModel.correctNum += 1 voicePlayer.playSuccessVoice() self.selectModels.removeAll() + let firstIndexCell = self.collectionView.cellForItem(at: firstM!.indexPath) as! ListenFight_Game_Pocket_CCell + let secondIndexCell = self.collectionView.cellForItem(at: lastM!.indexPath) as! ListenFight_Game_Pocket_CCell + firstIndexCell.setState(success: true) + secondIndexCell.setState(success: true) + DispatchQueue.main.asyncAfter(deadline: .now()+1.0) { + self.view.isUserInteractionEnabled = true + } + }else{ print("不相同") viewModel.answerType.accept(.fail) @@ -178,19 +190,25 @@ let firstIndexCell = self.collectionView.cellForItem(at: firstIndex!) as! ListenFight_Game_Pocket_CCell let secondIndexCell = self.collectionView.cellForItem(at: secondIndex!) as! ListenFight_Game_Pocket_CCell + firstIndexCell.setState(success: false) + secondIndexCell.setState(success: false) + self.view.isUserInteractionEnabled = false DispatchQueue.main.asyncAfter(deadline: .now()+3.0){ firstIndexCell.toBackAction(self.view) secondIndexCell.toBackAction(self.view) self.selectModels.removeAll() } + DispatchQueue.main.asyncAfter(wallDeadline: .now()+3.7){ + self.view.isUserInteractionEnabled = true + } } } let surplusListCount = datas.filter({$0.isOpen == false}).count if surplusListCount == 0{ - NotificationCenter.default.post(name: NextLession_Noti, object: ["gameId":listen1Model.data!.id,"gameIntegral":listen1Model.data!.integral]) rootViewModel.answerItems[0] = self.listen1Model + NotificationCenter.default.post(name: NextLession_Noti, object: ["gameId":listen1Model.data!.id,"gameIntegral":listen1Model.data!.answerIntegral]) timer?.invalidate() } print("剩余:\(surplusListCount)") @@ -224,7 +242,7 @@ if selectModels.count == 1{ let cell = self.collectionView.cellForItem(at: indexPath) as! ListenFight_Game_Pocket_CCell - cell.toFromAction(self.view) + cell.toFromAction(self.view,c: true) if model.type == 2{ //播放 @@ -302,17 +320,18 @@ extension HomeListenGame_2_VC:VoicePlayerDelegate{ func playComplete() { - view.isUserInteractionEnabled = true +// view.isUserInteractionEnabled = true //正在播放的语音Cell要归位 if let index = currentPayCellIndex{ let cell = collectionView.cellForItem(at: index) as! ListenFight_Game_Pocket_CCell cell.cellResotePay() + view.isUserInteractionEnabled = true } checking() } func playing() { - view.isUserInteractionEnabled = false +// view.isUserInteractionEnabled = false } } diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_1_VC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_1_VC.swift index 1af9ce1..6bf7575 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_1_VC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_1_VC.swift @@ -155,6 +155,12 @@ } case .fail: + weakSelf.isPlayedSet.removeAll() + for subV in weakSelf.stackView.arrangedSubviews as! [StudyHandleView]{ + subV.view_choose.alpha = 0 + subV.btn_choose.isSelected = false + } + weakSelf.viewModel.answerType.accept(.fail) weakSelf.rootViewModel.errorNum += 1 handleView.btn_state.setImage(UIImage(named: "icon_waring_small"), for: .normal) diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_2_VC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_2_VC.swift index 2a93c60..a919fc3 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_2_VC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenStory_2_VC.swift @@ -80,7 +80,7 @@ make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(24) make.centerX.equalToSuperview() make.height.equalTo(52) - make.width.greaterThanOrEqualTo(100) + make.width.equalTo(159) } for subV in stackView.arrangedSubviews{ diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift index 3a4ffb8..314f243 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenSubVC.swift @@ -14,8 +14,8 @@ private var page:Int! private var quarter:Int! private var week:Int! - private var tableView:UITableView! - private var studyScheduleModel:StudyScheduleModel? + private(set) var tableView:UITableView! + var studyScheduleModel:StudyScheduleModel? required init(page:Int,quarter:Int,week:Int,studyScheduleModel:StudyScheduleModel) { super.init(nibName: nil, bundle: nil) @@ -32,7 +32,6 @@ override func viewDidLoad() { super.viewDidLoad() navigationItem.titleView = UIView() -// getData() } override func setUI() { @@ -53,21 +52,25 @@ } override func setRx() { - NotificationCenter.default.rx.notification(Refresh_ListenSchedule_Noti).take(until: self.rx.deallocated).subscribe(onNext: {_ in - self.getData() - }).disposed(by: disposeBag) +// NotificationCenter.default.rx.notification(Refresh_ListenSchedule_Noti).take(until: self.rx.deallocated).subscribe(onNext: {_ in +// self.getData() +// }).disposed(by: disposeBag) } - private func getData(){ - Services.studySchedule(week: week).subscribe(onNext: {data in - self.studyScheduleModel = data.data - self.tableView.reloadData() - }).disposed(by: disposeBag) + private func getData(force:Bool = false){ + +// if studyScheduleModel == nil || force{ +// Services.studySchedule(week: week).subscribe(onNext: {data in +// self.studyScheduleModel = data.data +// self.tableView.reloadData() +// }).disposed(by: disposeBag) +// } + } func jumpAt(listenType:ListenType){ let row = listenType.rawValue - 1 - var jumpIndex:IndexPath = IndexPath(row: row, section: 0) + let jumpIndex:IndexPath = IndexPath(row: row, section: 1) tableView(self.tableView, didSelectRowAt: jumpIndex) } } @@ -78,6 +81,7 @@ if page <= 4 && indexPath.section == 0{return} let day = page + 1 + sceneDelegate?.startTimer() if page <= 4{ if indexPath.row == 0{ @@ -157,6 +161,7 @@ if indexPath.row == 0{ let fightVC = HomeListenFightVC(listenType: .game1,quarter: quarter,week: week,day: day) fightVC.title = ListenType.game1.rawTitle + fightVC.studyScheduleModel = studyScheduleModel JQ_currentViewController().jq_push(vc:fightVC) } if indexPath.row == 1{ diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift index af96be5..1df9ff8 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenVC.swift @@ -69,6 +69,12 @@ } } self.pageVC.reloadData() + + Services.onlineDuration().subscribe(onNext: { data in + if let time = data.data{ + sceneDelegate?.globalTimeval = time + } + }).disposed(by: disposeBag) } override func setUI() { @@ -125,6 +131,17 @@ } }).disposed(by: disposeBag) + + NotificationCenter.default.rx.notification(Refresh_ListenSchedule_Noti).take(until: self.rx.deallocated).subscribe(onNext: {_ in + Services.studySchedule(week: self.week).subscribe(onNext: {data in + self.studyScheduleModel = data.data + + for subVC in self.pageVC.children as! [HomeListenSubVC]{ + subVC.studyScheduleModel = self.studyScheduleModel + subVC.tableView.reloadData() + } + }).disposed(by: self.disposeBag) + }).disposed(by: disposeBag) } } diff --git a/DolphinEnglishLearnStudent/Moudle/Home/Listen/View/ChooseLevelView.swift b/DolphinEnglishLearnStudent/Moudle/Home/Listen/View/ChooseLevelView.swift index 2a71190..4faca1f 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/Listen/View/ChooseLevelView.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/Listen/View/ChooseLevelView.swift @@ -47,13 +47,13 @@ levelView.btn_level3.isEnabled = false switch canLevel { - case 3: + case 2: levelView.btn_level3.isEnabled = true fallthrough - case 2: + case 1: levelView.btn_level2.isEnabled = true fallthrough - case 1: + case 0: levelView.btn_level1.isEnabled = true default: levelView.btn_level1.isEnabled = true diff --git a/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.swift b/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.swift index 9f7b9a3..31784da 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.swift @@ -12,8 +12,11 @@ class HomeStudyCompleteVC: BaseVC { @IBOutlet weak var label_coin: UILabel! @IBOutlet weak var label_correctNum: UILabel! + @IBOutlet weak var label_title_correctNum: UILabel! @IBOutlet weak var label_totalNum: UILabel! + @IBOutlet weak var label_title_totalNum: UILabel! @IBOutlet weak var label_errorNum: UILabel! + @IBOutlet weak var label_title_errorNum: UILabel! @IBOutlet weak var label_ratioNum: UILabel! @IBOutlet weak var btn_next: UIButton! @IBOutlet weak var stackView: UIStackView! @@ -23,13 +26,15 @@ private var errorNum:Int = 0 private var totalCoin:Int = 0 private var listenType:ListenType! + private var totalNum:Int? //总题目数量 - required init(correctNum:Int,errorNum:Int,totalCoin:Int,listenType:ListenType){ + required init(correctNum:Int,errorNum:Int,totalCoin:Int,listenType:ListenType,totalNum:Int? = nil){ super.init(nibName: nil, bundle: nil) self.correctNum = correctNum self.errorNum = errorNum self.totalCoin = totalCoin self.listenType = listenType + self.totalNum = totalNum } required init?(coder: NSCoder) { @@ -49,12 +54,23 @@ label_totalNum.text = "\(correctNum + errorNum)次" label_ratioNum.text = String(format: "正确率:%.0lf%%", Double(correctNum) / Double(correctNum + errorNum) * 100) + if totalNum != nil{ + label_title_totalNum.text = "总题目:" + label_title_correctNum.text = "正确题目:" + label_title_errorNum.text = "错误题目:" + label_coin.text = "恭喜你,已完成游戏!获得\(totalCoin)积分!" + label_totalNum.text = "\(totalNum!)" + label_correctNum.text = "\(correctNum)" + label_errorNum.text = "\(errorNum)" + } + + btn_next.isHidden = listenType.rawValue >= 5 stackView.isHidden = listenType == .story2 label_ratioNum.isHidden = listenType == .story2 - NotificationCenter.default.post(name: Refresh_ListenSchedule_Noti, object: nil) +// NotificationCenter.default.post(name: Refresh_ListenSchedule_Noti, object: nil) } override func setUI() { diff --git a/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.xib b/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.xib index e0c1f7f..8663878 100644 --- a/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.xib +++ b/DolphinEnglishLearnStudent/Moudle/Home/VC/HomeStudyCompleteVC.xib @@ -17,6 +17,9 @@ <outlet property="label_correctNum" destination="GyL-R8-T1w" id="ljq-bs-33V"/> <outlet property="label_errorNum" destination="8Lo-W3-dxd" id="y0q-RX-MkE"/> <outlet property="label_ratioNum" destination="4uZ-XC-Xc3" id="cSZ-ND-O0D"/> + <outlet property="label_title_correctNum" destination="BK6-AS-rO7" id="wge-bu-2bn"/> + <outlet property="label_title_errorNum" destination="pPV-Gj-Ccs" id="uR0-E2-4xs"/> + <outlet property="label_title_totalNum" destination="ha0-SG-kAV" id="60c-GN-aG2"/> <outlet property="label_totalNum" destination="EAE-ID-4sP" id="Xpa-MR-y2Y"/> <outlet property="stackView" destination="ENd-BH-G5Q" id="zS4-oH-pyo"/> <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> diff --git a/DolphinEnglishLearnStudent/Moudle/Market/VC/MarketExchangeVC.swift b/DolphinEnglishLearnStudent/Moudle/Market/VC/MarketExchangeVC.swift index a525983..30d3882 100644 --- a/DolphinEnglishLearnStudent/Moudle/Market/VC/MarketExchangeVC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Market/VC/MarketExchangeVC.swift @@ -129,10 +129,10 @@ @IBAction func addNumAction(_ sender: UIButton) { var num = viewModel.number.value + 1 - if num >= viewModel.detailModel.value?.good?.userCount ?? 999{ - num = viewModel.detailModel.value?.good?.userCount ?? 999 - sender.isEnabled = false - } +// if num >= viewModel.detailModel.value?.good?.userCount ?? 999{ +// num = viewModel.detailModel.value?.good?.userCount ?? 999 +// sender.isEnabled = false +// } viewModel.number.accept(num) } diff --git a/DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.swift b/DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.swift index 66d8c9b..6343cc0 100644 --- a/DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.swift +++ b/DolphinEnglishLearnStudent/Moudle/Me/VC/StudyVC.swift @@ -22,7 +22,7 @@ self.tableView.reloadData() label_currentProcess.text = "当前进度:周目\(gamesRecordModel?.record?.week.jq_cn ?? "")" - label_surplusProcess.text = "剩余进度:周目\(gamesRecordModel?.record?.surplus.jq_cn ?? "")" + label_surplusProcess.text = "剩余进度:\(gamesRecordModel?.record?.surplus.jq_cn ?? "")周目" label_studyTotalTimes.attributedText = AttributedStringbuilder.build().add(string: "学习总时长:", withFont: .systemFont(ofSize: 16), withColor: UIColor(hexString: "#2B3648")!).add(string: "\(gamesRecordModel?.record?.totalStudy ?? 0)小时", withFont: .systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexString: "#2B3648")!).add(string: "|今日学习:", withFont: .systemFont(ofSize: 16), withColor: UIColor(hexString: "#2B3648")!).add(string: "\(gamesRecordModel?.record?.todayStudy ?? 0)小时", withFont: .systemFont(ofSize: 16, weight: .medium), withColor: UIColor(hexString: "#2B3648")!).mutableAttributedString diff --git a/DolphinEnglishLearnStudent/Other/UIView/CommonAlertView.swift b/DolphinEnglishLearnStudent/Other/UIView/CommonAlertView.swift index 483b6ea..2f609a8 100644 --- a/DolphinEnglishLearnStudent/Other/UIView/CommonAlertView.swift +++ b/DolphinEnglishLearnStudent/Other/UIView/CommonAlertView.swift @@ -16,6 +16,7 @@ @IBOutlet weak var cons_btnClose: NSLayoutConstraint! private var clouse:(()->Void)? + private var cancelClouse:(()->Void)? override func awakeFromNib() { super.awakeFromNib() self.alpha = 0 @@ -47,12 +48,35 @@ } } + static func showSimple(content:String,completeTitle:String? = nil,cancelClouse:@escaping (()->Void)){ + let commonAlertView = CommonAlertView.jq_loadNibView() + sceneDelegate?.window?.addSubview(commonAlertView) + commonAlertView.label_content.text = content + commonAlertView.label_content.numberOfLines = 0 + commonAlertView.label_content.textAlignment = .center + commonAlertView.cancelClouse = cancelClouse + commonAlertView.frame = sceneDelegate?.window?.frame ?? .zero + + commonAlertView.btn_complete.isHidden = true + commonAlertView.cons_btnClose.constant = 219 + commonAlertView.btn_close.backgroundColor = Config.ThemeColor + commonAlertView.btn_close.jq_borderWidth = 0 + commonAlertView.btn_close.setTitleColor(.white, for: .normal) + + UIView.animate(withDuration: 0.4) { + commonAlertView.alpha = 1 + commonAlertView.view_container.transform = .init(translationX: 1.0, y: 1.0) + commonAlertView.layoutIfNeeded() + } + } + @IBAction func closeAction(_ sender: UIButton) { UIView.animate(withDuration: 0.4) { self.alpha = 0 self.view_container.transform = .init(scaleX: 0.1, y: 0.1) } completion: { _ in self.removeFromSuperview() + self.cancelClouse?() } } diff --git a/DolphinEnglishLearnStudent/Other/UIView/StudyHandleView.xib b/DolphinEnglishLearnStudent/Other/UIView/StudyHandleView.xib index 047ccdf..a05c4aa 100644 --- a/DolphinEnglishLearnStudent/Other/UIView/StudyHandleView.xib +++ b/DolphinEnglishLearnStudent/Other/UIView/StudyHandleView.xib @@ -32,25 +32,33 @@ <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" image="icon_success_small"/> </button> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mz1-vG-vfG"> + <button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mz1-vG-vfG"> <rect key="frame" x="174" y="0.0" width="32" height="103"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <state key="normal" image="icon_play"/> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xZL-Va-yis"> + <rect key="frame" x="91" y="0.0" width="115" height="103"/> + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <connections> - <action selector="payAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="sgi-cA-rhG"/> + <action selector="payAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Hsm-4b-6ud"/> </connections> </button> </subviews> <color key="backgroundColor" red="0.25490196078431371" green="0.63529411764705879" blue="0.92156862745098034" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> + <constraint firstAttribute="bottom" secondItem="xZL-Va-yis" secondAttribute="bottom" id="6CU-mm-T5g"/> <constraint firstAttribute="bottom" secondItem="eGw-vD-STe" secondAttribute="bottom" id="IFe-rp-rkn"/> + <constraint firstItem="xZL-Va-yis" firstAttribute="top" secondItem="0XQ-2a-X00" secondAttribute="top" id="czD-UM-h2x"/> <constraint firstItem="mz1-vG-vfG" firstAttribute="top" secondItem="0XQ-2a-X00" secondAttribute="top" id="e9F-tS-4aU"/> <constraint firstItem="zhb-53-qPO" firstAttribute="centerX" secondItem="0XQ-2a-X00" secondAttribute="centerX" id="gg9-Bw-fEI"/> <constraint firstAttribute="bottom" secondItem="mz1-vG-vfG" secondAttribute="bottom" id="pKS-iN-MkG"/> <constraint firstItem="eGw-vD-STe" firstAttribute="top" secondItem="0XQ-2a-X00" secondAttribute="top" id="sSv-55-R5E"/> <constraint firstItem="zhb-53-qPO" firstAttribute="leading" secondItem="eGw-vD-STe" secondAttribute="trailing" constant="15" id="uxB-Ji-qbq"/> <constraint firstItem="zhb-53-qPO" firstAttribute="centerY" secondItem="0XQ-2a-X00" secondAttribute="centerY" id="vt0-xM-xhJ"/> + <constraint firstItem="mz1-vG-vfG" firstAttribute="trailing" secondItem="xZL-Va-yis" secondAttribute="trailing" id="zLf-iM-rKc"/> <constraint firstItem="mz1-vG-vfG" firstAttribute="leading" secondItem="zhb-53-qPO" secondAttribute="trailing" constant="9" id="zfI-8E-Wuj"/> + <constraint firstItem="eGw-vD-STe" firstAttribute="leading" secondItem="xZL-Va-yis" secondAttribute="leading" id="zsz-4a-8Nk"/> </constraints> <userDefinedRuntimeAttributes> <userDefinedRuntimeAttribute type="boolean" keyPath="ld_maskToBoundsXIB" value="YES"/> diff --git a/DolphinEnglishLearnStudent/Other/UIView/VoiceHandleView.swift b/DolphinEnglishLearnStudent/Other/UIView/VoiceHandleView.swift index 2d2e8a0..8907b6e 100644 --- a/DolphinEnglishLearnStudent/Other/UIView/VoiceHandleView.swift +++ b/DolphinEnglishLearnStudent/Other/UIView/VoiceHandleView.swift @@ -58,13 +58,20 @@ } addSubview(btn_play) - btn_play.addTarget(self, action: #selector(playingAction), for: .touchUpInside) + btn_play.isUserInteractionEnabled = false btn_play.snp.makeConstraints { make in make.right.equalTo(-23) make.centerY.equalToSuperview() make.width.equalTo(32) make.height.equalTo(32) } + + let playBtn = UIButton(type: .custom) + playBtn.addTarget(self, action: #selector(playingAction), for: .touchUpInside) + addSubview(playBtn) + playBtn.snp.makeConstraints { make in + make.edges.equalToSuperview() + } } required init?(coder: NSCoder) { diff --git a/DolphinEnglishLearnStudent/SceneDelegate.swift b/DolphinEnglishLearnStudent/SceneDelegate.swift index 584e611..1ad3441 100644 --- a/DolphinEnglishLearnStudent/SceneDelegate.swift +++ b/DolphinEnglishLearnStudent/SceneDelegate.swift @@ -109,20 +109,25 @@ func startTimer(){ guard let timeval = globalTimeval else {return} - timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {[weak self] timer in + + timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) {[weak self] timer in guard let weakSelf = self else { return } if let v = UserDefaults.standard.object(forKey: "scheduledTimer") as? TimeInterval{ if Date().timeIntervalSince1970 - v > Double(timeval) * 60.0{ - Services.giveIntegral().subscribe(onNext: { _ in - - }).disposed(by: weakSelf.disposeBag) - UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: "scheduledTimer") - UserDefaults.standard.synchronize() + Services.giveIntegral().subscribe(onNext: { _ in + UserDefaults.standard.set(Date().timeIntervalSince1970, forKey: "scheduledTimer") + UserDefaults.standard.synchronize() + }).disposed(by: weakSelf.disposeBag) } } } timer?.fire() RunLoop.current.add(timer!, forMode: .common) } + + func suspendTimer(){ + timer?.fireDate = .distantFuture + timer = nil + } } -- Gitblit v1.7.1