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

Add first steps: Welcome screen and build.gradle code injection screens #1

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ plugins {
group 'com.example'
version '1.0-SNAPSHOT'

sourceCompatibility = 11

repositories {
mavenCentral()
}
Expand All @@ -14,10 +16,21 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
}

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
version = '2020.3.3'
plugins = ['android']
}

//runIde {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this? Or add a comment of a reason why you would want to uncomment this, such as to test something specific.

// ideDir = file('/Users/PERSON/Library/Android/sdk')
//}

patchPluginXml {
changeNotes = """
Add change notes here.<br>
Expand Down
7 changes: 7 additions & 0 deletions src/main/kotlin/OneSignalStep.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import javax.swing.JPanel

interface OneSignalStep {

fun getContent(): JPanel

}
6 changes: 6 additions & 0 deletions src/main/kotlin/OneSignalStepListener.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
interface OneSignalStepListener {

fun onNextStep()
fun onStepCancel()

}
80 changes: 80 additions & 0 deletions src/main/kotlin/OneSignalToolWindowFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowFactory
import com.intellij.ui.content.ContentFactory

import sdksetup.SDKSetupFirstStepPanel
import sdksetup.SDKSetupSecondStepPanel
import utils.showNotification

import java.awt.CardLayout
import javax.swing.JComponent
import javax.swing.JPanel

class OneSignalToolWindowFactory : ToolWindowFactory, OneSignalStepListener {

private var project: Project? = null
private var toolWindow: ToolWindow? = null
private var mainPanel: JPanel? = null
private var mainCardLayout = CardLayout()

private var sdkSetupSteps = linkedMapOf<String, OneSignalStep>()
private var sdkSetupStepIndex = 0
private var welcomeKey = "welcome_panel"

/**
* Create the tool window content.
*
* @param project current project
* @param toolWindow current tool window
*/
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
this.project = project
this.toolWindow = toolWindow

// If basePath is null add step to get basePath
sdkSetupSteps["first_step_panel"] = SDKSetupFirstStepPanel(project.basePath!!, project, this@OneSignalToolWindowFactory)
sdkSetupSteps["second_step_panel"] = SDKSetupSecondStepPanel(project.basePath!!, project, this@OneSignalToolWindowFactory)

val welcomePanel = WelcomeScreenPanel(this@OneSignalToolWindowFactory)

this.mainPanel = JPanel(mainCardLayout).apply {
add(welcomePanel, welcomeKey)

sdkSetupSteps.entries.forEach {
add(it.value as JComponent, it.key)
}
}

val contentFactory = ContentFactory.SERVICE.getInstance()
val content = contentFactory.createContent(mainPanel, "", false)
toolWindow.contentManager.addContent(content)
}

override fun onNextStep() {
project?.let {
showNotification(it, "Navigating to next panel")
}

var index = 0
val keysIterator = sdkSetupSteps.keys.iterator()
while (keysIterator.hasNext()) {
val key = keysIterator.next()
if (index == sdkSetupStepIndex) {
sdkSetupStepIndex++
showPanel(key)
break
}
index++
}
}

override fun onStepCancel() {
sdkSetupStepIndex = 0
showPanel(welcomeKey)
}

private fun showPanel(panelName: String) {
mainCardLayout.show(mainPanel, panelName);
}
}
51 changes: 51 additions & 0 deletions src/main/kotlin/WelcomeScreenPanel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
import javax.swing.JButton
import javax.swing.JLabel
import javax.swing.JPanel

class WelcomeScreenPanel(private val stepListener: OneSignalStepListener) : JPanel(), OneSignalStep {

var welcomeLabel: JLabel
var nextButton: JButton

init {
welcomeLabel = JLabel("Welcome to OneSignal Plugin")
nextButton = JButton("Next")

initScreenPanel()
}

private fun initScreenPanel() {
layout = GridBagLayout()

var bagConstraints = GridBagConstraints()

// Welcome Label

bagConstraints.gridx = 1
bagConstraints.gridy = 0
bagConstraints.weightx = 1.0
bagConstraints.weighty = 1.0

add(welcomeLabel, bagConstraints)

// Next Button

bagConstraints.gridx = 1
bagConstraints.gridy = 1
bagConstraints.weightx = 1.0
bagConstraints.weighty = 0.1
add(nextButton, bagConstraints)

initListeners()
}

private fun initListeners() {
nextButton.addActionListener {
stepListener.onNextStep()
}
}

override fun getContent() = this
}
31 changes: 31 additions & 0 deletions src/main/kotlin/sdksetup/SDKSetupFirstStepController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package sdksetup

import com.intellij.openapi.project.Project
import utils.appendStringByMatch
import java.io.File

class SDKSetupFirstStepController {
/**
* Add dependencies to project level build.gradle file
*/
fun addSDKToBuildGradle(basePath: String, project: Project) {
val projectBuildGradle = File("$basePath/build.gradle")
var content: String = projectBuildGradle.readText()

content = content.appendStringByMatch("mavenCentral\\(\\)", "gradlePluginPortal()", "\n\t\t", project)
content = content.appendStringByMatch("jcenter\\(\\)", "gradlePluginPortal()", "\n\t\t", project)

content = content.appendStringByMatch(
"classpath 'com.android.tools.build:gradle:.+'",
"gradle.plugin.com.onesignal:onesignal-gradle-plugin",
"classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.9, 0.99.99]'", "\n\t\t", project
)
content = content.appendStringByMatch(
"classpath\\s\"com\\.android\\.tools\\.build:gradle:.+\"",
"gradle.plugin.com.onesignal:onesignal-gradle-plugin",
"classpath \"gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.9, 0.99.99]\"", "\n\t\t", project
)

projectBuildGradle.writeText(content)
}
}
93 changes: 93 additions & 0 deletions src/main/kotlin/sdksetup/SDKSetupFirstStepPanel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package sdksetup

import OneSignalStep
import OneSignalStepListener
import com.intellij.openapi.project.Project
import view.MultilineLabel
import java.awt.GridBagConstraints
import java.awt.GridBagLayout
import javax.swing.JButton
import javax.swing.JPanel

class SDKSetupFirstStepPanel(
private val basePath: String,
private val project: Project,
private val stepListener: OneSignalStepListener
) : JPanel(),
OneSignalStep {

private val controller = SDKSetupFirstStepController()
private val instructionString = """
OneSignal SDK needs the following changes in your build.gradle file

buildscript {

repositories {
...
gradlePluginPortal()
}

dependencies {

classpath 'com.onesignal:onesignal-gradle-plugin:[0.8.1, 0.99.99]'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to latest version, which is 0.14.0. Also we should probably have a shared definition for this version string, since it is used in multiple spots.

}
}

Be sure that before next button is clicked your Gradle is sync
"""
private var instructionsLabel: MultilineLabel = MultilineLabel(instructionString)
private var nextButton: JButton = JButton("Next")
private var cancelButton: JButton = JButton("Cancel")

init {

initScreenPanel()
}

private fun initScreenPanel() {
layout = GridBagLayout()

var bagConstraints = GridBagConstraints()

// Instructions Label

bagConstraints.gridy = 0
bagConstraints.fill = GridBagConstraints.HORIZONTAL
bagConstraints.weightx = 1.0
bagConstraints.weighty = 1.0

add(instructionsLabel, bagConstraints)

// Next Button

bagConstraints.gridy = 1
bagConstraints.gridx = 1
bagConstraints.weightx = 0.2
bagConstraints.weighty = 0.1

add(nextButton, bagConstraints)

// Cancel Button

bagConstraints.gridy = 1
bagConstraints.gridx = 0
bagConstraints.weightx = 0.2
bagConstraints.weighty = 0.1

add(cancelButton, bagConstraints)

initListeners()
}

private fun initListeners() {
nextButton.addActionListener {
controller.addSDKToBuildGradle(basePath, project)
stepListener.onNextStep()
}
cancelButton.addActionListener {
stepListener.onStepCancel()
}
}

override fun getContent() = this
}
68 changes: 68 additions & 0 deletions src/main/kotlin/sdksetup/SDKSetupSecondStepController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package sdksetup

import com.intellij.openapi.project.Project
import utils.appendStringByMatch
import java.io.File

class SDKSetupSecondStepController {

fun addSDKToAppBuildGradle(basePath: String, appDirectory: String, project: Project) {
addSDKToAppBuildGradle("$basePath/$appDirectory", project)
}

fun addSDKToAppBuildGradle(buildGradlePath: String, project: Project) {
val projectBuildGradle = File("$buildGradlePath/build.gradle")
var content: String = projectBuildGradle.readText()

// injecting com.onesignal:OneSignal dependency

content = content.appendStringByMatch(
"implementation \"androidx.appcompat:appcompat:[^']*\"",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These string searches look to be checking some possible dependences that the project might have. This doesn't look like it can account for any unexpected dependency so it looks like this approach won't work with may projects.

Did some searching and it looks like there is an Intellij API to read the build.gradle file and modify it (com.android.tools.idea.gradle.dsl.model.GradleBuildModel):
https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000106044-How-to-add-dependencies-to-gradle-file-from-IntelliJ-DEA-plugin-

"com.onesignal:OneSignal",
"implementation \"com.onesignal:OneSignal:[4.0.0, 4.99.99]\"",
"\n\t",
project
)
content = content.appendStringByMatch(
"implementation \"com.google.android.material:material:[^']*\"",
"com.onesignal:OneSignal",
"implementation \"com.onesignal:OneSignal:[4.0.0, 4.99.99]\"",
"\n\t",
project
)

content = content.appendStringByMatch(
"implementation 'androidx.appcompat:appcompat:[^']*'",
"com.onesignal:OneSignal",
"implementation 'com.onesignal:OneSignal:[4.0.0, 4.99.99]'",
"\n\t",
project
)
content = content.appendStringByMatch(
"implementation 'com.google.android.material:material:[^']*'",
"com.onesignal:OneSignal",
"implementation 'com.onesignal:OneSignal:[4.0.0, 4.99.99]'",
"\n\t",
project
)

// injecting onesignal-gradle-plugin

content = content.appendStringByMatch(
"apply plugin: 'com.android.application'",
"com.onesignal.androidsdk.onesignal-gradle-plugin",
"apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'",
"\n",
project
)
content = content.appendStringByMatch(
"id 'com.android.application'",
"com.onesignal.androidsdk.onesignal-gradle-plugin",
"id 'com.onesignal.androidsdk.onesignal-gradle-plugin'",
"\n\t",
project
)

projectBuildGradle.writeText(content)
}
}
Loading