Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
aac0aac
Create NewCodeQuiz module
ivan-magda Jul 9, 2019
659570e
Merge remote tracking branch origin/dev into feature/new-code-quiz
ivan-magda Jul 9, 2019
87fedda
Remove unused
ivan-magda Jul 9, 2019
7ee2e74
Initial for CodeTextView
ivan-magda Jul 10, 2019
14a262f
Merge remote tracking branch origin/dev into feature/new-code-quiz
ivan-magda Jul 16, 2019
c7e3e48
Fix swiftlint messages
ivan-magda Jul 17, 2019
11ae184
Remove unused infoBarButtonItem
ivan-magda Jul 17, 2019
c756f1c
Remove unused tooltipView property
ivan-magda Jul 17, 2019
d3cd0e8
Update request body logging
ivan-magda Jul 17, 2019
5b426a9
Fix typo
ivan-magda Jul 18, 2019
b5b5ce2
Sort BaseQuiz's files by name and type
ivan-magda Jul 18, 2019
d8d342a
Refactor rename group Child protocols -> ChildProtocols
ivan-magda Jul 18, 2019
1a9cd6b
Clean up
ivan-magda Jul 18, 2019
ea958cd
Fix typo
ivan-magda Jul 18, 2019
4c798c6
Add TODO
ivan-magda Jul 18, 2019
a817f16
Use optional string interpolation operator
ivan-magda Jul 18, 2019
57ac157
Sort quiz groups
ivan-magda Jul 18, 2019
ee2facd
Update comment
ivan-magda Jul 18, 2019
49daccf
Refactor rename separatorWidth -> separatorHeight
ivan-magda Jul 18, 2019
5c5b712
Fix set translatesAutoresizingMaskIntoConstraints to false
ivan-magda Jul 18, 2019
4aefac2
Refactor rename separatorWidth -> separatorHeight
ivan-magda Jul 18, 2019
b4e767e
Conform NewCodeQuizAssembly to QuizAssembly
ivan-magda Jul 19, 2019
6c598f1
Conform CodeLanguage to CaseIterable
ivan-magda Jul 19, 2019
38f766c
Sort quizzes group
ivan-magda Jul 19, 2019
75802a5
Remove checks for os(tvOS)
ivan-magda Jul 19, 2019
0ca6115
Add description properties
ivan-magda Jul 19, 2019
7553470
Create NewCodeQuizViewModel
ivan-magda Jul 19, 2019
39f9253
Init CodeReply with code and languageName
ivan-magda Jul 19, 2019
21bb2ab
Init for present & update reply
ivan-magda Jul 19, 2019
d1c3cd0
Provide step options
ivan-magda Jul 19, 2019
8d1dfc7
Display code details
ivan-magda Jul 23, 2019
2fb11b3
Rotate arrow image on click
ivan-magda Jul 23, 2019
a908fa1
Remove todo
ivan-magda Jul 23, 2019
c4c9b0c
Refactor rename
ivan-magda Jul 23, 2019
b8fa91b
Language picker header
ivan-magda Jul 23, 2019
3b1b5a2
Language picker select language
ivan-magda Jul 23, 2019
a3224a5
Conform to NewCodeQuizViewDelegate
ivan-magda Jul 23, 2019
8b27c44
Refactor rename
ivan-magda Jul 23, 2019
d1ed69c
Persist execution_time_limit and execution_memory_limit
ivan-magda Jul 23, 2019
06e2b0c
Multy line code sample and monospace font
ivan-magda Jul 23, 2019
061e50e
Update data flow
ivan-magda Jul 23, 2019
5c95d3f
Add final state
ivan-magda Jul 23, 2019
4b4dd60
Render code toolbar
ivan-magda Jul 23, 2019
2169c77
Add default state
ivan-magda Jul 24, 2019
1153ec5
Show code text view
ivan-magda Jul 24, 2019
a209557
Select language on state noLanguage
ivan-magda Jul 24, 2019
a5e4e49
Add newCodeQuizViewDidRequestFullscreen(_:)
ivan-magda Jul 24, 2019
f850f1c
Fix set language firstly
ivan-magda Jul 24, 2019
24bf740
Handle language selection on toolbar
ivan-magda Jul 24, 2019
758b5dc
Enable or disable controls based on current status
ivan-magda Jul 24, 2019
52b23e1
tmp
ivan-magda Jul 24, 2019
1c4fe3d
Fix issues with ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES
ivan-magda Jul 24, 2019
7ba2ab1
Setup theme
ivan-magda Jul 25, 2019
309ec61
Update code reply on text change
ivan-magda Jul 25, 2019
632ee42
Update SeparatorView appearance
ivan-magda Jul 25, 2019
f97815c
Use SeparatorView
ivan-magda Jul 25, 2019
a9c2dcd
Animate code details content alpha component
ivan-magda Jul 25, 2019
f999f61
Use SeparatorView
ivan-magda Jul 25, 2019
18d26b2
Output current code reply on language select
ivan-magda Jul 25, 2019
5cacc02
Update appearance of code editor
ivan-magda Jul 26, 2019
75eb1f5
Fix language chosen analytics param name
ivan-magda Jul 26, 2019
34cfba0
Auto select language if one
ivan-magda Jul 26, 2019
41bff9f
Do not clear current code and language on reply update
ivan-magda Jul 26, 2019
dfb5d34
Disable code text view auto correction features
ivan-magda Jul 26, 2019
f54c8e7
Refactor rename notSupportedLanguage -> unsupportedLanguage
ivan-magda Jul 30, 2019
7860785
Handle empty state for code language picker
ivan-magda Jul 30, 2019
78e7fa8
Handle unsupported code language
ivan-magda Jul 30, 2019
521fc02
Update Podfile.lock
ivan-magda Jul 30, 2019
fc876a1
Code completion and suggestions
ivan-magda Jul 30, 2019
240de20
Use partial from operator
ivan-magda Jul 30, 2019
298082f
Rearrange code
ivan-magda Jul 30, 2019
94e2489
Fix toolbar collapse after language picked
ivan-magda Jul 30, 2019
0a59661
tmp
ivan-magda Jul 30, 2019
c47a13f
Update visibility flow
ivan-magda Jul 30, 2019
9ec978f
Remove unused
ivan-magda Jul 30, 2019
465a0a8
Select code suggestion if text view editable
ivan-magda Jul 30, 2019
35a7e05
Make setupAccessoryView(isEditable:) private
ivan-magda Jul 30, 2019
6a94438
Display language name inside of code editor
ivan-magda Jul 30, 2019
7c85fb1
Provide step text content
ivan-magda Jul 31, 2019
d842c73
Display fullscreen
ivan-magda Jul 31, 2019
68aa4fd
Display tabs
ivan-magda Jul 31, 2019
aa73464
Fix index out of bounds
ivan-magda Jul 31, 2019
5156f30
tmp
ivan-magda Aug 1, 2019
732aaa6
Set backgroundColor
ivan-magda Aug 5, 2019
fd59792
Create CodeEditorSettingsLegacyAssembly
ivan-magda Aug 5, 2019
36f88f8
Add todo's
ivan-magda Aug 5, 2019
ec91147
Remove unused
ivan-magda Aug 5, 2019
7cee58b
Update todo with lesson title
ivan-magda Aug 5, 2019
2df1ce8
Create StepOptionsPersistenceService
ivan-magda Aug 5, 2019
ddf2133
StepOptions to plain object
ivan-magda Aug 5, 2019
4d44d78
Initial for NewCodeQuizProvider
ivan-magda Aug 5, 2019
12e2874
Create CodeDetails
ivan-magda Aug 5, 2019
830b168
Update child quiz input with code details
ivan-magda Aug 5, 2019
8048f57
Use code details
ivan-magda Aug 6, 2019
8851604
Refactor rename
ivan-magda Aug 6, 2019
0df71f2
Refactor rename codeLanguage -> language
ivan-magda Aug 6, 2019
a1890e0
Update presenter
ivan-magda Aug 6, 2019
b743c16
Create code editor theme service
ivan-magda Aug 6, 2019
cf31cda
Update fullscreen
ivan-magda Aug 6, 2019
711d3f9
Use plain objects
ivan-magda Aug 6, 2019
6a415ee
Set title for fullscreen
ivan-magda Aug 6, 2019
08936a1
Update & submit reply
ivan-magda Aug 6, 2019
009188e
Refactor rename SomeAction to ContentLoad
ivan-magda Aug 6, 2019
5bbce28
Auto update code editor theme
ivan-magda Aug 6, 2019
6748f32
Refactor rename
ivan-magda Aug 6, 2019
225d872
reset
ivan-magda Aug 6, 2019
c89df8c
Update default code editor theme
ivan-magda Aug 6, 2019
efcf410
Merge remote tracking branch origin/dev into feature/new-code-quiz
ivan-magda Aug 6, 2019
9cc1d03
Delete after merge
ivan-magda Aug 6, 2019
8d1dc0f
Undo changes for NewLessonViewController
ivan-magda Aug 6, 2019
9de42c1
Move down
ivan-magda Aug 6, 2019
706db2b
Set space between pages
ivan-magda Aug 6, 2019
233287d
Add Swift support
ivan-magda Aug 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 0c6f3046cd7795142e613d85d7621ac20ce19346

COCOAPODS: 1.7.4
COCOAPODS: 1.7.5
332 changes: 287 additions & 45 deletions Stepic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Stepic/AlamofireRequestsLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class AlamofireRequestsLogger {

if let httpBody = request.httpBody,
let httpBodyString = String(data: httpBody, encoding: .utf8) {
print(httpBodyString)
print("Body: \(httpBodyString)")
}
}
}
4 changes: 2 additions & 2 deletions Stepic/CodeEditorPreferencesContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class CodeEditorPreferencesContainer {
if let value = defaults.value(forKey: themeKey) as? String {
return value
} else {
self.theme = "androidstudio"
return "androidstudio"
self.theme = "xcode"
return "xcode"
}
}

Expand Down
10 changes: 9 additions & 1 deletion Stepic/CodeEditorSettingsPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protocol CodeEditorSettingsView: class {
func updatePreview(fontSize: Int)
}

class CodeEditorSettingsPresenter {
final class CodeEditorSettingsPresenter {
weak var view: CodeEditorSettingsView?

var themeBlock: TransitionMenuBlock?
Expand All @@ -34,12 +34,16 @@ class CodeEditorSettingsPresenter {
PreferencesContainer.codeEditor.theme = newTheme
themeBlock?.subtitle = String(format: NSLocalizedString("CodeEditorCurrentTheme", comment: ""), newTheme)
view?.updatePreview(theme: newTheme)

NotificationCenter.default.post(name: .codeEditorThemeDidChange, object: nil)
}

func updateFontSize(with newSize: Int) {
PreferencesContainer.codeEditor.fontSize = newSize
fontSizeBlock?.subtitle = String(format: NSLocalizedString("CodeEditorCurrentFontSize", comment: ""), "\(newSize)")
view?.updatePreview(fontSize: newSize)

NotificationCenter.default.post(name: .codeEditorThemeDidChange, object: nil)
}

private func buildSettingsMenu() -> Menu {
Expand Down Expand Up @@ -87,3 +91,7 @@ class CodeEditorSettingsPresenter {
return fontSizeBlock!
}
}

extension NSNotification.Name {
static let codeEditorThemeDidChange = NSNotification.Name("codeEditorThemeDidChange")
}
174 changes: 112 additions & 62 deletions Stepic/CodeEditorSettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,116 @@
// Created by Vladislav Kiryukhin on 11.04.18.
// Copyright © 2018 Alex Karpov. All rights reserved.
//
import UIKit

import ActionSheetPicker_3_0
import UIKit

@available(*, deprecated, message: "Class to initialize code editor settings w/o storyboards logic")
final class CodeEditorSettingsLegacyAssembly: Assembly {
private let previewLanguage: CodeLanguage

init(previewLanguage: CodeLanguage = .python) {
self.previewLanguage = previewLanguage
}

func makeModule() -> UIViewController {
guard let viewController = ControllerHelper.instantiateViewController(
identifier: "CodeEditorSettings",
storyboardName: "Profile"
) as? CodeEditorSettingsViewController else {
fatalError("Failed to initialize CodeEditorSettingsViewController")
}

let presenter = CodeEditorSettingsPresenter(view: viewController)
viewController.presenter = presenter
viewController.previewLanguage = self.previewLanguage

class CodeEditorSettingsViewController: MenuViewController, CodeEditorSettingsView {
return viewController
}
}

final class CodeEditorSettingsViewController: MenuViewController {
var presenter: CodeEditorSettingsPresenter?
var previewView: CodeEditorPreviewView!
var previewLanguage = CodeLanguage.python

private lazy var previewView: CodeEditorPreviewView = {
let previewView = CodeEditorPreviewView()
previewView.delegate = self
return previewView
}()

override func viewDidLoad() {
super.viewDidLoad()

edgesForExtendedLayout = []

previewView = CodeEditorPreviewView()
previewView.delegate = self
tableView.tableHeaderView = previewView
layoutTableHeaderView()
self.edgesForExtendedLayout = []
self.tableView.tableHeaderView = self.previewView

presenter = CodeEditorSettingsPresenter(view: self)
self.layoutTableHeaderView()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
previewView.setupPreview(with: PreferencesContainer.codeEditor.theme, fontSize: PreferencesContainer.codeEditor.fontSize, language: previewLanguage)

// TODO: Add injection for theme.
self.previewView.setupPreview(
with: PreferencesContainer.codeEditor.theme,
fontSize: PreferencesContainer.codeEditor.fontSize,
language: self.previewLanguage
)
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
self.layoutTableHeaderView()
}

private func layoutTableHeaderView() {
guard let tableHeaderView = self.tableView.tableHeaderView else {
return
}

tableHeaderView.translatesAutoresizingMaskIntoConstraints = false

let headerWidth = tableHeaderView.bounds.size.width
let widthConstraint = tableHeaderView.widthAnchor.constraint(equalToConstant: headerWidth)
widthConstraint.isActive = true

tableHeaderView.setNeedsLayout()
tableHeaderView.layoutIfNeeded()

var frame = tableHeaderView.frame
frame.size.height = tableHeaderView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
tableHeaderView.frame = frame

tableHeaderView.removeConstraint(widthConstraint)
tableHeaderView.translatesAutoresizingMaskIntoConstraints = true
self.tableView.tableHeaderView = tableHeaderView
}
}

extension CodeEditorSettingsViewController: CodeEditorSettingsView {
func setMenu(menu: Menu) {
self.menu = menu
}

func chooseEditorTheme(current: String) {
guard let hl = previewView.highlightr,
let currentThemeIndex = hl.availableThemes().index(of: current) else {
guard let highlightr = self.previewView.highlightr,
let currentThemeIndex = highlightr.availableThemes().index(of: current) else {
return
}

ActionSheetStringPicker.show(withTitle: NSLocalizedString("CodeEditorTheme", comment: ""),
rows: hl.availableThemes(),
ActionSheetStringPicker.show(
withTitle: NSLocalizedString("CodeEditorTheme", comment: ""),
rows: highlightr.availableThemes(),
initialSelection: currentThemeIndex,
doneBlock: { _, _, value in
doneBlock: { [weak self] _, _, value in
if let value = value as? String {
self.presenter?.updateTheme(with: value)
self?.presenter?.updateTheme(with: value)
}
},
cancel: { _ in },
origin: previewView)
origin: self.previewView
)
}

func chooseFontSize(current: Int) {
Expand All @@ -56,72 +124,54 @@ class CodeEditorSettingsViewController: MenuViewController, CodeEditorSettingsVi
return
}

ActionSheetStringPicker.show(withTitle: NSLocalizedString("CodeEditorFontSize", comment: ""),
ActionSheetStringPicker.show(
withTitle: NSLocalizedString("CodeEditorFontSize", comment: ""),
rows: availableSizes.map { "\($0)" },
initialSelection: currentSizeIndex,
doneBlock: { _, _, value in
doneBlock: { [weak self] _, _, value in
if let value = value as? String, let intValue = Int(value) {
self.presenter?.updateFontSize(with: intValue)
self?.presenter?.updateFontSize(with: intValue)
}
},
cancel: { _ in },
origin: previewView)
origin: self.previewView
)
}

func updatePreview(theme: String) {
previewView?.updateTheme(with: theme)
self.previewView.updateTheme(with: theme)
}

func updatePreview(fontSize: Int) {
previewView?.updateFontSize(with: fontSize)
}

func setMenu(menu: Menu) {
self.menu = menu
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
layoutTableHeaderView()
}

func layoutTableHeaderView() {
guard let headerView = tableView.tableHeaderView else {
return
}
headerView.translatesAutoresizingMaskIntoConstraints = false

let headerWidth = headerView.bounds.size.width
let widthConstraint = headerView.widthAnchor.constraint(equalToConstant: headerWidth)
widthConstraint.isActive = true

headerView.setNeedsLayout()
headerView.layoutIfNeeded()

var frame = headerView.frame
frame.size.height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
headerView.frame = frame

headerView.removeConstraint(widthConstraint)
headerView.translatesAutoresizingMaskIntoConstraints = true
tableView.tableHeaderView = headerView
self.previewView.updateFontSize(with: fontSize)
}
}

extension CodeEditorSettingsViewController: CodeEditorPreviewViewDelegate {
func languageButtonDidClick() {
let availableLanguages = Array(Set(CodeLanguage.allLanguages.map { $0.humanReadableName }))
let availableLanguages = Array(Set(CodeLanguage.allCases.map { $0.humanReadableName }))

ActionSheetStringPicker.show(withTitle: NSLocalizedString("CodeEditorLanguage", comment: ""),
guard let currentLanguageIndex = availableLanguages.index(of: self.previewLanguage.humanReadableName) else {
return
}

ActionSheetStringPicker.show(
withTitle: NSLocalizedString("CodeEditorLanguage", comment: ""),
rows: availableLanguages,
initialSelection: availableLanguages.index(of: previewLanguage.humanReadableName)!,
doneBlock: { _, _, value in
initialSelection: currentLanguageIndex,
doneBlock: { [weak self] _, _, value in
guard let strongSelf = self else {
return
}

if let value = value as? String {
self.previewLanguage = CodeLanguage.allLanguages.first(where: { $0.humanReadableName == value }) ?? self.previewLanguage
self.previewView.updateLanguage(with: self.previewLanguage)
let newPreviewLanguage = CodeLanguage.allCases.first(where: { $0.humanReadableName == value })
strongSelf.previewLanguage = newPreviewLanguage ?? strongSelf.previewLanguage
strongSelf.previewView.updateLanguage(with: strongSelf.previewLanguage)
}
},
cancel: { _ in },
origin: previewView.languageButton)
origin: self.previewView.languageButton
)
}
}
16 changes: 0 additions & 16 deletions Stepic/CodeLanguagePickerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,4 @@ class CodeLanguagePickerViewController: PickerViewController {
picker.selectRow(start, inComponent: 0, animated: false)
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/

}
14 changes: 8 additions & 6 deletions Stepic/CodeLanguages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

enum CodeLanguage: String {
enum CodeLanguage: String, CaseIterable {
case python = "python3"
case cpp11 = "c++11"
case cpp = "c++"
Expand Down Expand Up @@ -36,11 +36,7 @@ enum CodeLanguage: String {
case pascal = "pascalabc"
case perl = "perl"
case sql = "sql"

static let allLanguages: [CodeLanguage] = [.python, .cpp11, .cpp, .c, .haskell, .haskell7,
.haskell8, .java, .java8, .java9, .java11, .octave, .asm32, .asm64,
.shell, .rust, .r, .ruby, .clojure, .cs, .javascript,
.scala, .kotlin, .go, .pascal, .perl, .sql]
case swift = "swift"

var highlightr: String {
switch self {
Expand Down Expand Up @@ -82,6 +78,8 @@ enum CodeLanguage: String {
return "perl"
case .sql:
return "sql"
case .swift:
return "swift"
}
}

Expand Down Expand Up @@ -125,6 +123,8 @@ enum CodeLanguage: String {
return "Perl"
case .sql:
return "SQL"
case .swift:
return "Swift"
}
}

Expand Down Expand Up @@ -172,6 +172,8 @@ enum CodeLanguage: String {
return "# comment\nprint \"Hello World!\\n\";"
case .sql:
return "# comment\n\nSELECT 'Hello World';"
case .swift:
return "// comment\nprint(\"Hello World!\")"
}
}
}
5 changes: 4 additions & 1 deletion Stepic/CodeLimit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import CoreData
import SwiftyJSON

class CodeLimit: NSManagedObject {

var language: CodeLanguage? {
return CodeLanguage(rawValue: languageString)
}

override var description: String {
return "CodeLimit(languageString: \(self.languageString), time: \(self.time), memory: \(self.memory)"
}

convenience required init(language: String, json: JSON) {
self.init()
initialize(language: language, json: json)
Expand Down
15 changes: 15 additions & 0 deletions Stepic/CodeLimitPlainObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation

struct CodeLimitPlainObject {
let language: String?
let memory: Double
let time: TimeInterval
}

extension CodeLimitPlainObject {
init(codeLimit: CodeLimit) {
self.language = codeLimit.languageString
self.memory = codeLimit.memory
self.time = codeLimit.time
}
}
Loading