Skip to content

Commit

Permalink
feat(android): add kotlin template and code base flag
Browse files Browse the repository at this point in the history
Closes TIMOB-27906

Co-authored-by: Hans Knöchel <hansemannn@users.noreply.github.com>
  • Loading branch information
2 people authored and sgtcoolguy committed Jul 14, 2020
1 parent fd53a51 commit 23c3aea
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 6 deletions.
Expand Up @@ -4,8 +4,6 @@
Similar to tiapp.xml, but contains module/platform specific
configuration in <iphone> and <android> sections
-->
<iphone>
</iphone>
<android xmlns:android="http://schemas.android.com/apk/res/android">
</android>
</ti:module>
@@ -0,0 +1,86 @@
/**
* This file was auto-generated by the Titanium Module SDK helper for Android
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2020 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*
*/

package <%- moduleId %>

import android.app.Activity
import org.appcelerator.kroll.KrollDict
import org.appcelerator.kroll.annotations.Kroll.*
import org.appcelerator.kroll.common.Log
import org.appcelerator.kroll.common.TiConfig
import org.appcelerator.titanium.TiC
import org.appcelerator.titanium.proxy.TiViewProxy
import org.appcelerator.titanium.util.TiConvert
import org.appcelerator.titanium.view.TiCompositeLayout
import org.appcelerator.titanium.view.TiCompositeLayout.LayoutArrangement
import org.appcelerator.titanium.view.TiUIView

// This proxy can be created by calling <%- moduleNameCamel %>.createExample({ message: 'hello world' })
@proxy(creatableInModule = <%- moduleNameCamel %>Module::class)
class ExampleProxy : TiViewProxy() {

companion object {
// Standard Debugging variables
private const val LCAT = "ExampleProxy"
private val DBG = TiConfig.LOGD
}

private inner class ExampleView(proxy: TiViewProxy) : TiUIView(proxy) {
override fun processProperties(d: KrollDict) {
super.processProperties(d)
}

init {
var arrangement = LayoutArrangement.DEFAULT
if (proxy.hasProperty(TiC.PROPERTY_LAYOUT)) {
val layoutProperty = TiConvert.toString(proxy.getProperty(TiC.PROPERTY_LAYOUT))
if (layoutProperty == TiC.LAYOUT_HORIZONTAL) {
arrangement = LayoutArrangement.HORIZONTAL
} else if (layoutProperty == TiC.LAYOUT_VERTICAL) {
arrangement = LayoutArrangement.VERTICAL
}
}
setNativeView(TiCompositeLayout(proxy.activity, arrangement))
}
}

override fun createView(activity: Activity): TiUIView {
val view: TiUIView = ExampleView(this)
view.layoutParams.autoFillsHeight = true
view.layoutParams.autoFillsWidth = true
return view
}

// Handle creation options
override fun handleCreationDict(options: KrollDict) {
super.handleCreationDict(options)
if (options.containsKey("message")) {
Log.d(LCAT, "example created with message: " + options["message"])
}
}

// Methods

@method
fun printMessage(message: String) {
Log.d(LCAT, "printing message: $message")
}

// Properties

@get:method
@get:getProperty
@set:method
@set:setProperty
var message: String
get() = "Hello World from my module"
set(message) {
Log.d(LCAT, "Tried setting module message to: $message")
}
}
@@ -0,0 +1,80 @@
/**
* This file was auto-generated by the Titanium Module SDK helper for Android
* Appcelerator Titanium Mobile
* Copyright (c) 2009-present by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*
*/

package <%- moduleId %>;

import org.appcelerator.kroll.KrollModule
import org.appcelerator.kroll.KrollDict
import org.appcelerator.kroll.annotations.Kroll.*
import org.appcelerator.kroll.common.Log
import org.appcelerator.kroll.common.TiConfig
import org.appcelerator.titanium.TiApplication

@module(name = "<%- moduleNameCamel %>", id = "ti.<%- moduleId %>")
class <%- moduleNameCamel %>Module: KrollModule() {

// NOTE: You can develop Titanium Android modules in Android Studio. Follow these three steps:
// 1. Build the empty module
// 2. Drag the "build" folder into Android Studio
// 3. Start developing! All dependencies and code completions are supported!

companion object {
// Standard Debugging variables
private const val LCAT = "<%- moduleNameCamel %>Module"
private val DBG = TiConfig.LOGD

// You can define constants with @Kroll.constant, for example:
// @constant private val EXTERNAL_NAME = "EXTERNAL_NAME"

@onAppCreate
fun onAppCreate(app: TiApplication?) {
Log.d(LCAT, "inside onAppCreate")
// put module init code that needs to run when the application is created
}
}

// Methods

@method
fun example(): String {
Log.d(LCAT, "example() called")
return "hello world"
}

@method
fun testMethod(params: KrollDict) {
Log.d(LCAT, "testMethod() called")

// Access the parameters passed as an Object, e.g. "myModule.testMethod({ name: 'John Doe', flag: true })"
val name = params.getString("name")
val flag = params.optBoolean("flag", false);

// Fire an event that can be added via "myModule.addEventListener('shown', ...)"
val event = KrollDict()
event["name"] = name
event["flag"] = flag

fireEvent("", event)
}

// Properties

@get:getProperty
@get:method
@set:setProperty
@set:method
var exampleProp: String
get() {
Log.d(LCAT, "get example property")
return "hello world"
}
set(value) {
Log.d(LCAT, "set example property: $value")
}
}
69 changes: 65 additions & 4 deletions cli/lib/creators/module.js
Expand Up @@ -19,6 +19,7 @@ const appc = require('node-appc'),
ti = require('node-titanium-sdk'),
util = require('util'),
uuid = require('node-uuid'),
fields = require('fields'),
__ = appc.i18n(__dirname).__;

/**
Expand Down Expand Up @@ -80,7 +81,52 @@ ModuleCreator.prototype.init = function init() {
platforms: this.configOptionPlatforms(120),
template: this.configOptionTemplate(110),
'workspace-dir': this.configOptionWorkspaceDir(170),
'code-base': this.configOptionCodeBase(150)
'code-base': this.configOptionCodeBase(150),
'android-code-base': this.configOptionAndroidCodeBase(150)

}
};
};

/**
* Defines the --android-code-base option to select the code base (Java or Kotlin).
*
* @param {Integer} order - The order to apply to this option.
*
* @returns {Object}
*/
ModuleCreator.prototype.configOptionAndroidCodeBase = function configAndroidCodeBase(order) {
const cli = this.cli;
const validTypes = [ 'java', 'kotlin' ];
const logger = this.logger;

function validate(value, callback) {
if (!value || !validTypes.includes(value)) {
logger.error(__('Please specify a valid code base') + '\n');
return callback(true);
}
callback(null, value);
}

return {
desc: __('the code base of the Android project'),
order: order,
default: !cli.argv.prompt ? 'java' : undefined,
prompt: function (callback) {
callback(fields.text({
promptLabel: __('Android code base (' + validTypes.join('|') + ')'),
default: 'java',
validate: validate
}));
},
required: true,
validate: validate,
values: validTypes,
verifyIfRequired: function (callback) {
if (cli.argv.platforms.includes('android')) {
return callback(true);
}
return callback();
}
};
};
Expand Down Expand Up @@ -152,7 +198,15 @@ ModuleCreator.prototype.run = function run(callback) {
platforms.scrubbed.forEach(function (platform) {
// if we're using the built-in template, load the platform specific template hooks
const usingBuiltinTemplate = templateDir.indexOf(this.sdk.path) === 0;
const templateBaseDir = platform === 'iphone' ? this.cli.argv['code-base'] : this.cli.argv.template;
let templateBaseDir = this.cli.argv.template;

if (platform === 'iphone' && this.cli.argv['code-base']) {
templateBaseDir = this.cli.argv['code-base'];
} else if (platform === 'android' && this.cli.argv['android-code-base']) {
templateBaseDir = this.cli.argv['android-code-base'];
}

const defaultTemplateDir = path.join(this.sdk.path, platform, 'templates', this.projectType, 'default');
const platformTemplateDir = path.join(this.sdk.path, platform, 'templates', this.projectType, templateBaseDir);

if (usingBuiltinTemplate) {
Expand All @@ -172,12 +226,19 @@ ModuleCreator.prototype.run = function run(callback) {
if (usingBuiltinTemplate) {
this.cli.createHook('create.copyFiles.platform.' + platform, this, function (vars, done) {
this.logger.info(__('Copying %s platform resources', platform.cyan));
this.copyDir(path.join(platformTemplateDir, 'template'), projectDir, function () {
appc.async.series(this, [
(cb) => {
this.copyDir(path.join(defaultTemplateDir, 'template'), projectDir, cb, vars);
},
(cb) => {
this.copyDir(path.join(platformTemplateDir, 'template'), projectDir, cb, vars);
},
], () => {
this.cli.emit([
'create.post.' + this.projectType + '.platform.' + platform,
'create.post.platform.' + platform
], this, done);
}.bind(this), vars);
});
}.bind(this))(appc.util.mix({ platform: platform }, variables), next);
return;
}
Expand Down

0 comments on commit 23c3aea

Please sign in to comment.