Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text color, background text color, image, video, and tables functions aren't working. #23

Open
lucychen0103 opened this issue Mar 13, 2022 · 8 comments
Labels
question Further information is requested

Comments

@lucychen0103
Copy link

I can click on the icon but the functions aren't working. Does anyone have any insight?

@Andrew-Chen-Wang
Copy link
Owner

Logs/output/the HTML itself would be great!

@Andrew-Chen-Wang Andrew-Chen-Wang added question Further information is requested bug Something isn't working and removed question Further information is requested bug Something isn't working labels Mar 13, 2022
@Andrew-Chen-Wang
Copy link
Owner

Are you using the Example RichEditorProject? The code for actually implementing the video is a customizable feature from a delegate. Take a look how we implement the insert link functionality. Due to different people's different needs, it was not implemented.

Here's what you could do:

  • If you just want users to upload a video from their library, you can follow a tutorial where a popup can appear asking the user to select a video mimetype file
  • If you want to also be able to insert videos from online, that's where the insertVideo functionality comes in with server side implementation.
  • You may also want to consider how customized your video-js will be (since we import that in the HTML file)

Unfortunately, it's too tailored to whatever your needs are, so the example doesn't provide. I guess I could provide an example later.

In the example app, just append the following:

<div><video class='video-js' controls preload='auto'  data-setup='{}'><source src='https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_1MB.mp4'></source></video></div>

Hope that helps!

@lucychen0103
Copy link
Author

Thanks @Andrew-Chen-Wang! I'll take a swipe at implementing the video function tomorrow after I wake up.
In the meantime, may you redirect me to where the code for insertImage is being called so that I may troubleshoot? I can't find any of the implementations for the functions that are being called when the icons are clicked for some reason. Do I need to download the original repo as well to access? Thanks!

@Andrew-Chen-Wang
Copy link
Owner

Andrew-Chen-Wang commented Mar 13, 2022

You should be able to find the insertImage function in Sources/RichEditorView/RichEditorView.swift and find the actual delegates at the top of the file like where the link delegate method is.

So the way the editor works is that every time you press an icon, we run a swift method that calls runJS in Sources/RichEditorView/RichEditorView.swift. This executes a javascript function in a javascript file called rich_editor.js under Resources/editor (hence you can decorate the editor using the rich_editor.html file and even include other JS or CSS files). We're running all this in a WKWebView.

Unless it's private, do you mind creating a PR with whatever you come up with in the example RichEditorProject? You can play around with the example by opening the XCode project under the Example dir. Only if you don't mind tho!

And yea np! but also hope that helps :P

@lucychen0103 lucychen0103 changed the title Image, video, and tables functions aren't working. Text color, background text color, image, video, and tables functions aren't working. Mar 14, 2022
@lucychen0103
Copy link
Author

lucychen0103 commented Mar 14, 2022

@Andrew-Chen-Wang With your help, I finished all of the functions that weren't working before.
I'm not using the example RichEditorProject so I can't make a PR but here is my code!

extension TextController: RichEditorToolbarDelegate, UIImagePickerControllerDelegate, UIColorPickerViewControllerDelegate {
    
//had to resize image because otherwise it would be too big
    func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage {

       let scale = newWidth / image.size.width
       let newHeight = image.size.height * scale
        UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
        image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()!
       UIGraphicsEndImageContext()

       return newImage
   }
    
//insert image and video functionality 
    func richEditorToolbarInsertImage(_ toolbar: RichEditorToolbar){
        var imagePicker = UIImagePickerController()
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
              imagePicker.delegate = self
              imagePicker.sourceType = .photoLibrary
              imagePicker.allowsEditing = false
              present(imagePicker, animated: true, completion: nil)
          }
    }
    
    func richEditorToolbarInsertVideo(_ toolbar: RichEditorToolbar){
        var picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .savedPhotosAlbum
        picker.mediaTypes = ["public.movie"]
        picker.allowsEditing = false
        present(picker, animated: true, completion: nil)
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true, completion: nil)
        let randomInt = Int.random(in: 0..<10000)
        if((info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerMediaType") ] as! String) == "public.movie" ){
          // Video file
            let videoURL = info[UIImagePickerController.InfoKey(rawValue: UIImagePickerController.InfoKey.mediaURL.rawValue) ] as? NSURL
             print(videoURL!)
            toolbar.editor?.insertVideo(vidURL: (videoURL?.absoluteString)!, posterURL: "", isBase64: false)
        }
        else{
            if var image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                guard let imageURL = NSURL(fileURLWithPath:
                                            NSTemporaryDirectory()).appendingPathComponent(String(randomInt) + ".png") else {
                    return
                }
                image = resizeImage(image: image, newWidth: view.bounds.width)
                let pngData = image.pngData();
                do {
                    try pngData?.write(to: imageURL);
                } catch {
                    print("can't save image")
                }
                toolbar.editor?.insertImage(imageURL.absoluteString, alt: "(image can't be shown)")
            }
        }
        
        

    }

//text and background color 
    func richEditorToolbarChangeTextColor(_ toolbar: RichEditorToolbar) {
        let colorPicker = UIColorPickerViewController()
        colorPicker.delegate = self
        changeTextColor = true
        present(colorPicker, animated: true, completion: nil)
    }
    
    func richEditorToolbarChangeBackgroundColor(_ toolbar: RichEditorToolbar) {
        let colorPicker = UIColorPickerViewController()
        colorPicker.delegate = self
        changeBackgroundColor = true
        present(colorPicker, animated: true, completion: nil)
    }


    func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
        if changeTextColor {
            toolbar.editor?.setTextColor(viewController.selectedColor)
            changeTextColor = false
        }
        else if changeBackgroundColor {
            toolbar.editor?.setTextBackgroundColor(viewController.selectedColor)
            changeBackgroundColor = false
        }
        
    }
    
//insert table function, made an alert controller to customize the height and width of table
    func richEditorToolbarInsertTable(_ toolbar: RichEditorToolbar) {
        let alertController = UIAlertController(title: "Enter height and width", message: "", preferredStyle: .alert)
        let confirmAction = UIAlertAction(title: "Insert", style: .default) { (_) in
            var height = alertController.textFields?[0].text
            let width = alertController.textFields?[1].text
            toolbar.editor?.insertTable(width: Int(width!) ?? 2, height: Int(height!) ?? 2)
            self.editorView.focus()
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
        alertController.addAction(confirmAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
        confirmAction.isEnabled = true
        let heightPH = "Height (required)"
        let widthPH = "Width (required)"
        alertController.addTextField { (textField) in
            textField.placeholder = heightPH
        }
        alertController.addTextField { (textField) in textField.placeholder = widthPH }
    }

//already here, found in example RichEditorProject not written by me 
    func isURLValid(url: String?) -> Bool {
        if(url?.hasPrefix("http://") ?? false || url?.hasPrefix("https://") ?? false) { return true }
        return false
    }

    func richEditorToolbarInsertLink(_ toolbar: RichEditorToolbar) {
        let alertController = UIAlertController(title: "Enter link and text", message: "You can leave the text empty to only show a clickable link", preferredStyle: .alert)
        let confirmAction = UIAlertAction(title: "Insert", style: .default) { (_) in
            var link = alertController.textFields?[0].text
            let text = alertController.textFields?[1].text
            if link?.last != "/" { link = link! + "/" }
            toolbar.editor?.insertLink(href: link!, text: text ?? link!)
            self.editorView.focus()
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
        alertController.addAction(confirmAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
        confirmAction.isEnabled = false
        let linkPH = "Link (required)"
        let txtPH = "Text (Clickable text that redirects)"
        toolbar.editor?.hasRangeSelection(handler: { r in
            if r == true {
                alertController.addTextField { (textField) in
                    textField.placeholder = linkPH
                    toolbar.editor?.getSelectedHref(handler: { a in
                        if a?.last != "/" {
                            textField.text = nil
                        } else {
                            if self.isURLValid(url: a) == true {
                                textField.text = a
                            }
                        }
                    })
                    NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: textField, queue: OperationQueue.main) { (notification) in
                        if self.isURLValid(url: textField.text) == true {
                            confirmAction.isEnabled = textField.hasText
                        } else {
                            confirmAction.isEnabled = false
                        }
                    }
                }
                alertController.addTextField { (textField) in
                    textField.placeholder = txtPH
                    toolbar.editor?.getSelectedText(handler: { a in
                        textField.text = a
                    })
                }
            } else {
                alertController.addTextField { (textField) in
                    textField.placeholder = linkPH
                    NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: textField, queue: OperationQueue.main) { (notification) in
                        if self.isURLValid(url: textField.text) == true {
                            confirmAction.isEnabled = textField.hasText
                        } else {
                            confirmAction.isEnabled = false
                        }
                    }
                }
                alertController.addTextField { (textField) in textField.placeholder = txtPH }
            }
        })
    }
}

@Andrew-Chen-Wang
Copy link
Owner

@lucychen0103 this is great! Thanks so much!

@rmi111
Copy link

rmi111 commented May 31, 2022

What is TextControlleer here?

@lucychen0103
Copy link
Author

@rmi111 It's just a class. You can change the name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants