@maccesar/titools 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS-TEMPLATE.md +173 -0
- package/README.md +867 -0
- package/agents/ti-researcher.md +108 -0
- package/bin/titools.js +53 -0
- package/lib/commands/agents.js +126 -0
- package/lib/commands/install.js +188 -0
- package/lib/commands/uninstall.js +215 -0
- package/lib/commands/update.js +159 -0
- package/lib/config.js +119 -0
- package/lib/downloader.js +153 -0
- package/lib/installer.js +253 -0
- package/lib/platform.js +108 -0
- package/lib/symlink.js +142 -0
- package/lib/utils.js +270 -0
- package/package.json +67 -0
- package/skills/alloy-expert/SKILL.md +247 -0
- package/skills/alloy-expert/assets/ControllerAutoCleanup.js +182 -0
- package/skills/alloy-expert/references/alloy-structure.md +381 -0
- package/skills/alloy-expert/references/anti-patterns.md +133 -0
- package/skills/alloy-expert/references/code-conventions.md +469 -0
- package/skills/alloy-expert/references/contracts.md +280 -0
- package/skills/alloy-expert/references/controller-patterns.md +520 -0
- package/skills/alloy-expert/references/error-handling.md +484 -0
- package/skills/alloy-expert/references/examples.md +735 -0
- package/skills/alloy-expert/references/migration-patterns.md +298 -0
- package/skills/alloy-expert/references/patterns.md +448 -0
- package/skills/alloy-expert/references/performance-patterns.md +855 -0
- package/skills/alloy-expert/references/security-patterns.md +847 -0
- package/skills/alloy-expert/references/state-management.md +779 -0
- package/skills/alloy-expert/references/testing.md +872 -0
- package/skills/alloy-guides/SKILL.md +214 -0
- package/skills/alloy-guides/references/CLI_TASKS.md +243 -0
- package/skills/alloy-guides/references/CONCEPTS.md +191 -0
- package/skills/alloy-guides/references/CONTROLLERS.md +298 -0
- package/skills/alloy-guides/references/MODELS.md +1028 -0
- package/skills/alloy-guides/references/PURGETSS.md +56 -0
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +242 -0
- package/skills/alloy-guides/references/VIEWS_STYLES.md +388 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +109 -0
- package/skills/alloy-guides/references/VIEWS_XML.md +558 -0
- package/skills/alloy-guides/references/WIDGETS.md +176 -0
- package/skills/alloy-howtos/SKILL.md +203 -0
- package/skills/alloy-howtos/references/best_practices.md +138 -0
- package/skills/alloy-howtos/references/cli_reference.md +253 -0
- package/skills/alloy-howtos/references/config_files.md +87 -0
- package/skills/alloy-howtos/references/custom_tags.md +147 -0
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +101 -0
- package/skills/alloy-howtos/references/samples.md +167 -0
- package/skills/purgetss/SKILL.md +442 -0
- package/skills/purgetss/assets/purgetss.config.cjs +17 -0
- package/skills/purgetss/references/EXAMPLES.md +247 -0
- package/skills/purgetss/references/animation-system.md +1294 -0
- package/skills/purgetss/references/apply-directive.md +375 -0
- package/skills/purgetss/references/arbitrary-values.md +612 -0
- package/skills/purgetss/references/class-index.md +1350 -0
- package/skills/purgetss/references/cli-commands.md +948 -0
- package/skills/purgetss/references/configurable-properties.md +654 -0
- package/skills/purgetss/references/custom-rules.md +161 -0
- package/skills/purgetss/references/customization-deep-dive.md +722 -0
- package/skills/purgetss/references/dynamic-component-creation.md +489 -0
- package/skills/purgetss/references/grid-layout.md +455 -0
- package/skills/purgetss/references/icon-fonts.md +609 -0
- package/skills/purgetss/references/installation-setup.md +366 -0
- package/skills/purgetss/references/opacity-modifier.md +291 -0
- package/skills/purgetss/references/platform-modifiers.md +479 -0
- package/skills/purgetss/references/smart-mappings.md +42 -0
- package/skills/purgetss/references/titanium-resets.md +359 -0
- package/skills/purgetss/references/ui-ux-design.md +1526 -0
- package/skills/ti-guides/SKILL.md +94 -0
- package/skills/ti-guides/references/advanced-data-and-images.md +19 -0
- package/skills/ti-guides/references/alloy-cli-advanced.md +84 -0
- package/skills/ti-guides/references/alloy-data-mastery.md +29 -0
- package/skills/ti-guides/references/alloy-widgets-and-themes.md +19 -0
- package/skills/ti-guides/references/android-manifest.md +97 -0
- package/skills/ti-guides/references/app-distribution.md +258 -0
- package/skills/ti-guides/references/application-frameworks.md +377 -0
- package/skills/ti-guides/references/cli-reference.md +402 -0
- package/skills/ti-guides/references/coding-best-practices.md +102 -0
- package/skills/ti-guides/references/commonjs-advanced.md +134 -0
- package/skills/ti-guides/references/hello-world.md +100 -0
- package/skills/ti-guides/references/hyperloop-native-access.md +62 -0
- package/skills/ti-guides/references/javascript-primer.md +411 -0
- package/skills/ti-guides/references/reserved-words.md +36 -0
- package/skills/ti-guides/references/resources.md +183 -0
- package/skills/ti-guides/references/style-and-conventions.md +48 -0
- package/skills/ti-guides/references/tiapp-config.md +609 -0
- package/skills/ti-howtos/SKILL.md +174 -0
- package/skills/ti-howtos/references/android-platform-deep-dives.md +658 -0
- package/skills/ti-howtos/references/automation-fastlane-appium.md +95 -0
- package/skills/ti-howtos/references/buffer-codec-streams.md +140 -0
- package/skills/ti-howtos/references/cross-platform-development.md +348 -0
- package/skills/ti-howtos/references/debugging-profiling.md +543 -0
- package/skills/ti-howtos/references/extending-titanium.md +723 -0
- package/skills/ti-howtos/references/google-maps-v2.md +169 -0
- package/skills/ti-howtos/references/ios-map-kit.md +143 -0
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +783 -0
- package/skills/ti-howtos/references/local-data-sources.md +301 -0
- package/skills/ti-howtos/references/location-and-maps.md +252 -0
- package/skills/ti-howtos/references/media-apis.md +210 -0
- package/skills/ti-howtos/references/notification-services.md +599 -0
- package/skills/ti-howtos/references/remote-data-sources.md +349 -0
- package/skills/ti-howtos/references/tutorials.md +502 -0
- package/skills/ti-howtos/references/using-modules.md +237 -0
- package/skills/ti-howtos/references/web-content-integration.md +307 -0
- package/skills/ti-howtos/references/webpack-build-pipeline.md +78 -0
- package/skills/ti-ui/SKILL.md +179 -0
- package/skills/ti-ui/references/accessibility-deep-dive.md +242 -0
- package/skills/ti-ui/references/animation-and-matrices.md +599 -0
- package/skills/ti-ui/references/application-structures.md +655 -0
- package/skills/ti-ui/references/custom-fonts-styling.md +579 -0
- package/skills/ti-ui/references/event-handling.md +393 -0
- package/skills/ti-ui/references/gestures.md +473 -0
- package/skills/ti-ui/references/icons-and-splash-screens.md +409 -0
- package/skills/ti-ui/references/layouts-and-positioning.md +462 -0
- package/skills/ti-ui/references/listviews-and-performance.md +619 -0
- package/skills/ti-ui/references/orientation.md +362 -0
- package/skills/ti-ui/references/platform-ui-android.md +635 -0
- package/skills/ti-ui/references/platform-ui-ios.md +469 -0
- package/skills/ti-ui/references/scrolling-views.md +252 -0
- package/skills/ti-ui/references/tableviews.md +568 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# Alloy MVC + PurgeTSS Structure Reference
|
|
2
|
+
|
|
3
|
+
## Standard Project Structure
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
app/
|
|
7
|
+
├── controllers/ # View orchestrators
|
|
8
|
+
│ ├── index.js # Bootstrap only (no business logic)
|
|
9
|
+
│ └── feature/
|
|
10
|
+
│ └── list.js # Controller for list view
|
|
11
|
+
├── models/ # OPTIONAL: For persistence with migrations
|
|
12
|
+
│ └── user.js # Model definition (ONLY if using SQLite)
|
|
13
|
+
├── views/ # XML views styled with PurgeTSS
|
|
14
|
+
│ ├── index.xml
|
|
15
|
+
│ └── feature/
|
|
16
|
+
│ ├── list.xml # View definition (Utility classes here)
|
|
17
|
+
├── lib/ # Reusable logic (no UI)
|
|
18
|
+
│ ├── api/
|
|
19
|
+
│ │ └── client.js # API calls
|
|
20
|
+
│ ├── services/
|
|
21
|
+
│ │ ├── auth.js # Business logic services
|
|
22
|
+
│ │ ├── navigation.js # Navigation orchestration
|
|
23
|
+
│ │ ├── nativeService.js # Native module wrapper (e.g. Audio, FB, Maps)
|
|
24
|
+
│ │ └── purgetss.animation.js # PurgeTSS Animation module
|
|
25
|
+
│ └── helpers/
|
|
26
|
+
│ ├── utils.js # Pure utility functions
|
|
27
|
+
│ └── i18n.js # Complex string transformations
|
|
28
|
+
├── widgets/ # Truly reusable components (used in 3+ places)
|
|
29
|
+
│ └── customButton/
|
|
30
|
+
├── styles/ # Global styles
|
|
31
|
+
│ ├── app.tss # GENERATED by PurgeTSS (Do not edit)
|
|
32
|
+
│ ├── _app.tss # YOUR custom styles (persists across runs)
|
|
33
|
+
│ └── fonts.tss # GENERATED by PurgeTSS build-fonts
|
|
34
|
+
├── config.json # Alloy configuration
|
|
35
|
+
└── alloy.js # Collections & Global services
|
|
36
|
+
|
|
37
|
+
./purgetss/
|
|
38
|
+
├── config.cjs # PurgeTSS theme configuration
|
|
39
|
+
└── styles/
|
|
40
|
+
└── utilities.tss # All utility classes
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## lib/ Folder and Module Require Paths
|
|
44
|
+
|
|
45
|
+
:::danger CRITICAL: lib/ Folder is FLATTENED During Build
|
|
46
|
+
When Alloy compiles, the **entire `lib/` folder is flattened to the root of Resources**. This means:
|
|
47
|
+
- `app/lib/services/picsum.js` → `Resources/iphone/services/picsum.js`
|
|
48
|
+
- `app/lib/api/client.js` → `Resources/iphone/api/client.js`
|
|
49
|
+
|
|
50
|
+
**Therefore, require statements should NOT include `lib/` prefix:**
|
|
51
|
+
```javascript
|
|
52
|
+
// ❌ WRONG - Will fail at runtime
|
|
53
|
+
const client = require('lib/api/client')
|
|
54
|
+
|
|
55
|
+
// ✅ CORRECT - Path relative to flattened lib/
|
|
56
|
+
const client = require('api/client')
|
|
57
|
+
const picsum = require('services/picsum')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**This applies to:**
|
|
61
|
+
- All files in `app/lib/` (services, api, helpers, etc.)
|
|
62
|
+
- Cross-references within lib/ files
|
|
63
|
+
- Controller requires of lib/ files
|
|
64
|
+
|
|
65
|
+
**Example project structure:**
|
|
66
|
+
```
|
|
67
|
+
app/
|
|
68
|
+
├── lib/
|
|
69
|
+
│ ├── services/
|
|
70
|
+
│ │ ├── picsum.js # require('services/logger')
|
|
71
|
+
│ │ ├── navigation.js # require('services/logger')
|
|
72
|
+
│ │ └── logger.js
|
|
73
|
+
│ └── api/
|
|
74
|
+
│ └── client.js # require('services/logger')
|
|
75
|
+
├── controllers/
|
|
76
|
+
│ └── index.js # require('services/picsum')
|
|
77
|
+
```
|
|
78
|
+
:::
|
|
79
|
+
|
|
80
|
+
## Data Layer: Two Approaches
|
|
81
|
+
|
|
82
|
+
### Approach A: Alloy Models (app/models/) - For Persistence
|
|
83
|
+
|
|
84
|
+
**Use when:**
|
|
85
|
+
- You need SQLite persistence
|
|
86
|
+
- You need schema migrations between app versions
|
|
87
|
+
- You need offline-first functionality
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
// app/models/User.js
|
|
91
|
+
exports.definition = {
|
|
92
|
+
config: {
|
|
93
|
+
columns: {
|
|
94
|
+
id: 'INTEGER PRIMARY KEY',
|
|
95
|
+
name: 'TEXT',
|
|
96
|
+
email: 'TEXT'
|
|
97
|
+
},
|
|
98
|
+
adapter: {
|
|
99
|
+
type: 'sql',
|
|
100
|
+
collection_name: 'users'
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Usage
|
|
106
|
+
const users = Alloy.createCollection('User')
|
|
107
|
+
users.fetch()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### Approach B: Backbone Collections Direct (alloy.js) - For API Data
|
|
113
|
+
|
|
114
|
+
**Use when:**
|
|
115
|
+
- Data comes from APIs
|
|
116
|
+
- No local persistence needed
|
|
117
|
+
- You want simplicity and flexibility
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
// alloy.js - Define collections globally
|
|
121
|
+
Alloy.Collections.frames = new Backbone.Collection()
|
|
122
|
+
Alloy.Collections.mockups = new Backbone.Collection()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**In views - bind with dataCollection:**
|
|
126
|
+
```xml
|
|
127
|
+
<ListSection id="section" dataCollection="frames">
|
|
128
|
+
<ListItem title:text="{title}" />
|
|
129
|
+
</ListSection>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**In controllers - manipulate directly:**
|
|
133
|
+
```javascript
|
|
134
|
+
// Reset collection
|
|
135
|
+
Alloy.Collections.frames.reset()
|
|
136
|
+
|
|
137
|
+
// Add items
|
|
138
|
+
Alloy.Collections.frames.add(newItem)
|
|
139
|
+
|
|
140
|
+
// Fetch from API
|
|
141
|
+
api.getFrames()
|
|
142
|
+
.then(frames => Alloy.Collections.frames.reset(frames))
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Controller Rules
|
|
146
|
+
|
|
147
|
+
**DO:**
|
|
148
|
+
- Use **PurgeTSS classes** in XML for 100% of the styling.
|
|
149
|
+
- Orchestrate view and model/collection interactions.
|
|
150
|
+
- Handle UI events and delegate to services.
|
|
151
|
+
- Format data for display (simple cases).
|
|
152
|
+
- Manage view lifecycle (including cleanup).
|
|
153
|
+
|
|
154
|
+
**DON'T:**
|
|
155
|
+
- Create per-controller `.tss` files (Use PurgeTSS utility classes).
|
|
156
|
+
- Make direct API calls (use lib/api/ or lib/services/).
|
|
157
|
+
- Contain heavy business logic.
|
|
158
|
+
- Call native modules directly (use a service wrapper).
|
|
159
|
+
|
|
160
|
+
## Navigation & Cleanup Pattern
|
|
161
|
+
|
|
162
|
+
### Automatic Cleanup with ControllerAutoCleanup
|
|
163
|
+
|
|
164
|
+
For automatic controller cleanup without code changes, use the ControllerAutoCleanup utility.
|
|
165
|
+
|
|
166
|
+
**Installation:**
|
|
167
|
+
|
|
168
|
+
1. Copy `ControllerAutoCleanup.js` to `app/lib/`
|
|
169
|
+
2. Add as first line in `alloy.js`:
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
// alloy.js
|
|
173
|
+
require('ControllerAutoCleanup')
|
|
174
|
+
|
|
175
|
+
// Rest of your alloy.js initialization...
|
|
176
|
+
Alloy.Collections.frames = new Backbone.Collection()
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**How it works:**
|
|
180
|
+
|
|
181
|
+
- Monkey-patches `Alloy.createController` to add automatic cleanup
|
|
182
|
+
- Listens for `close` events and recursively cleans up controllers
|
|
183
|
+
- No code changes needed - existing `Alloy.createController().getView().open()` calls get cleanup automatically
|
|
184
|
+
|
|
185
|
+
**Benefits:**
|
|
186
|
+
|
|
187
|
+
| Without ControllerAutoCleanup | With ControllerAutoCleanup |
|
|
188
|
+
| ------------------------------------------ | -------------------------- |
|
|
189
|
+
| Must remember manual cleanup | Cleanup automatic |
|
|
190
|
+
| Easy to forget, causes memory leaks | Memory leaks prevented |
|
|
191
|
+
| Repetitive code in each navigation service | One-line install |
|
|
192
|
+
|
|
193
|
+
See [ControllerAutoCleanup.js](../assets/ControllerAutoCleanup.js) for the complete source code.
|
|
194
|
+
|
|
195
|
+
## i18n and Accessibility Rules
|
|
196
|
+
|
|
197
|
+
- All static text must use `L('key')`.
|
|
198
|
+
- All interactive elements must have `accessibilityLabel`.
|
|
199
|
+
- Use `lib/helpers/i18n.js` for strings that require logic (e.g., "You have 5 messages").
|
|
200
|
+
- Use **PurgeTSS modifiers** for platform-specific design instead of conditional code.
|
|
201
|
+
|
|
202
|
+
## Widget Structure
|
|
203
|
+
|
|
204
|
+
Widgets are self-contained, reusable components used in 3+ places across the app.
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
app/widgets/
|
|
208
|
+
└── loadingOverlay/
|
|
209
|
+
├── controllers/
|
|
210
|
+
│ └── widget.js # Main widget controller
|
|
211
|
+
├── views/
|
|
212
|
+
│ └── widget.xml # Main widget view
|
|
213
|
+
├── styles/
|
|
214
|
+
│ └── widget.tss # Widget-specific styles (optional with PurgeTSS)
|
|
215
|
+
└── widget.json # Widget manifest
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### widget.json Configuration
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"id": "com.app.loadingOverlay",
|
|
222
|
+
"name": "Loading Overlay",
|
|
223
|
+
"description": "Full-screen loading indicator with optional message",
|
|
224
|
+
"author": "Your Name",
|
|
225
|
+
"version": "1.0.0",
|
|
226
|
+
"copyright": "Copyright (c) 2024",
|
|
227
|
+
"license": "MIT",
|
|
228
|
+
"min-alloy-version": "1.0.0",
|
|
229
|
+
"min-titanium-version": "9.0.0",
|
|
230
|
+
"tags": "ui, loading",
|
|
231
|
+
"platforms": "android,ios"
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Widget View (widget.xml)
|
|
236
|
+
```xml
|
|
237
|
+
<Alloy>
|
|
238
|
+
<View id="container" class="wh-screen hidden bg-black/50">
|
|
239
|
+
<View class="wh-32 vertical rounded-2xl bg-white">
|
|
240
|
+
<ActivityIndicator id="spinner" class="mt-6" />
|
|
241
|
+
<Label id="messageLabel" class="mx-4 mt-4 text-sm text-gray-600" />
|
|
242
|
+
</View>
|
|
243
|
+
</View>
|
|
244
|
+
</Alloy>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Widget Controller (widget.js)
|
|
248
|
+
```javascript
|
|
249
|
+
// Widget controller receives args via $.args
|
|
250
|
+
const args = $.args || {}
|
|
251
|
+
|
|
252
|
+
// Initialize with defaults
|
|
253
|
+
let message = args.message || L('loading')
|
|
254
|
+
|
|
255
|
+
// Public API
|
|
256
|
+
$.show = (msg) => {
|
|
257
|
+
if (msg) message = msg
|
|
258
|
+
$.messageLabel.text = message
|
|
259
|
+
$.spinner.show()
|
|
260
|
+
$.container.visible = true
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
$.hide = () => {
|
|
264
|
+
$.spinner.hide()
|
|
265
|
+
$.container.visible = false
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
$.setMessage = (msg) => {
|
|
269
|
+
$.messageLabel.text = msg
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Cleanup
|
|
273
|
+
$.cleanup = () => {
|
|
274
|
+
$.spinner.hide()
|
|
275
|
+
$.destroy()
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Using Widgets
|
|
280
|
+
```xml
|
|
281
|
+
<!-- In any view -->
|
|
282
|
+
<Alloy>
|
|
283
|
+
<Window>
|
|
284
|
+
<!-- Your content -->
|
|
285
|
+
|
|
286
|
+
<!-- Add widget -->
|
|
287
|
+
<Widget id="loader" src="loadingOverlay" message="L('please_wait')" />
|
|
288
|
+
</Window>
|
|
289
|
+
</Alloy>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
// In controller
|
|
294
|
+
const loadData = () => {
|
|
295
|
+
$.loader.show(L('loading_data'))
|
|
296
|
+
|
|
297
|
+
api.fetchData()
|
|
298
|
+
.then(renderData)
|
|
299
|
+
.finally(() => $.loader.hide())
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
:::tip PurgeTSS with Widgets
|
|
304
|
+
If your widget uses PurgeTSS utility classes (as shown in the example above), you must enable widget processing in `./purgetss/config.cjs`:
|
|
305
|
+
|
|
306
|
+
```javascript
|
|
307
|
+
// ./purgetss/config.cjs
|
|
308
|
+
module.exports = {
|
|
309
|
+
purge: {
|
|
310
|
+
options: {
|
|
311
|
+
widgets: true // Enable PurgeTSS class processing for widgets
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Without this setting, PurgeTSS will NOT process classes in widget files.
|
|
318
|
+
:::
|
|
319
|
+
|
|
320
|
+
## config.json Reference
|
|
321
|
+
|
|
322
|
+
The `app/config.json` file configures Alloy compilation and runtime behavior.
|
|
323
|
+
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"global": {
|
|
327
|
+
"theme": "default"
|
|
328
|
+
},
|
|
329
|
+
"env:development": {
|
|
330
|
+
"apiUrl": "https://dev-api.example.com",
|
|
331
|
+
"debug": true,
|
|
332
|
+
"logLevel": "debug"
|
|
333
|
+
},
|
|
334
|
+
"env:test": {
|
|
335
|
+
"apiUrl": "https://staging-api.example.com",
|
|
336
|
+
"debug": true,
|
|
337
|
+
"logLevel": "info"
|
|
338
|
+
},
|
|
339
|
+
"env:production": {
|
|
340
|
+
"apiUrl": "https://api.example.com",
|
|
341
|
+
"debug": false,
|
|
342
|
+
"logLevel": "error"
|
|
343
|
+
},
|
|
344
|
+
"os:android": {
|
|
345
|
+
"androidSpecificSetting": true
|
|
346
|
+
},
|
|
347
|
+
"os:ios": {
|
|
348
|
+
"iosSpecificSetting": true
|
|
349
|
+
},
|
|
350
|
+
"dependencies": {
|
|
351
|
+
"com.app.loadingOverlay": "1.0"
|
|
352
|
+
},
|
|
353
|
+
"autoStyle": false,
|
|
354
|
+
"backbone": "1.4.0",
|
|
355
|
+
"sourcemap": true
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Accessing Config Values
|
|
360
|
+
```javascript
|
|
361
|
+
// In any controller or lib file
|
|
362
|
+
const apiUrl = Alloy.CFG.apiUrl
|
|
363
|
+
const isDebug = Alloy.CFG.debug
|
|
364
|
+
const logLevel = Alloy.CFG.logLevel
|
|
365
|
+
|
|
366
|
+
// Environment check
|
|
367
|
+
if (Alloy.CFG.debug) {
|
|
368
|
+
console.log('Debug mode enabled')
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Key Configuration Options
|
|
373
|
+
|
|
374
|
+
| Property | Description |
|
|
375
|
+
| -------------- | ------------------------------------------------- |
|
|
376
|
+
| `theme` | Theme folder to use from `app/themes/` |
|
|
377
|
+
| `autoStyle` | Auto-apply TSS styles (set `false` with PurgeTSS) |
|
|
378
|
+
| `backbone` | Backbone.js version to use |
|
|
379
|
+
| `sourcemap` | Generate source maps for debugging |
|
|
380
|
+
| `dependencies` | Widget dependencies and versions |
|
|
381
|
+
| `adaptersPath` | Custom path for sync adapters |
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Titanium Alloy + PurgeTSS Anti-Patterns
|
|
2
|
+
|
|
3
|
+
## 1. Manual Styling (Legacy & Overwrite Risk)
|
|
4
|
+
**Symptom:** Editing `app.tss` manually or using inline attributes like `backgroundColor="#fff"`.
|
|
5
|
+
**Problem:** PurgeTSS will overwrite manual changes in `app.tss`. Inline attributes make theme changes impossible.
|
|
6
|
+
**Solution:** Use **PurgeTSS classes** in XML.
|
|
7
|
+
|
|
8
|
+
## 2. Fat Controllers
|
|
9
|
+
**Symptom:** Controllers with 100+ lines handling logic, API, and UI.
|
|
10
|
+
**Solution:** Delegate business logic to `lib/services/` and API calls to `lib/api/`.
|
|
11
|
+
|
|
12
|
+
## 3. Memory Leaks (Missing Cleanup)
|
|
13
|
+
**Symptom:** Adding `Ti.App` or `Alloy.Collections` listeners without a `cleanup()` function.
|
|
14
|
+
**Solution:** Always implement `$.cleanup = cleanup` and remove listeners there.
|
|
15
|
+
|
|
16
|
+
## 4. Direct Native Module Calls
|
|
17
|
+
**Symptom:** Calling `require('ti.module')` directly in a controller.
|
|
18
|
+
**Solution:** Wrap it in a service in `lib/services/` (e.g., `audioService.js`).
|
|
19
|
+
|
|
20
|
+
## 5. Direct Controller Navigation
|
|
21
|
+
**Symptom:** `Alloy.createController('name').getView().open()`.
|
|
22
|
+
**Solution:** Use a Navigation Service to centralize `open/close` and trigger the `cleanup()` function automatically.
|
|
23
|
+
|
|
24
|
+
## 6. Complex Matrix Animations
|
|
25
|
+
**Symptom:** Manual use of `Ti.UI.create2DMatrix()`.
|
|
26
|
+
**Solution:** Use the **PurgeTSS Animation Module** with state modifiers (`class="close:opacity-0 open:opacity-100"`).
|
|
27
|
+
|
|
28
|
+
## 7. Hardcoded Strings & Missing a11y
|
|
29
|
+
**Symptom:** `text="Login"` instead of `text="L('login')"`, or missing `accessibilityLabel`.
|
|
30
|
+
**Solution:** Always use i18n and accessibility properties.
|
|
31
|
+
|
|
32
|
+
## 8. Logic in TSS
|
|
33
|
+
**Symptom:** Using conditionals or calculations inside TSS.
|
|
34
|
+
**Solution:** Keep styling declarative through PurgeTSS classes.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## PurgeTSS-Specific Anti-Patterns
|
|
39
|
+
|
|
40
|
+
## 9. Flexbox Classes (Don't Exist)
|
|
41
|
+
**Symptom:** Using `flex-row`, `flex-col`, `justify-between`, `justify-center`, `items-center`.
|
|
42
|
+
**Problem:** Titanium does NOT support CSS Flexbox. These classes don't exist in PurgeTSS.
|
|
43
|
+
**Solution:** Use Titanium layout modes:
|
|
44
|
+
```xml
|
|
45
|
+
<!-- WRONG -->
|
|
46
|
+
<View class="flex-row justify-between">
|
|
47
|
+
|
|
48
|
+
<!-- CORRECT -->
|
|
49
|
+
<View class="horizontal">
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 10. Padding on Container Views
|
|
53
|
+
**Symptom:** Using `p-4`, `px-2`, `py-3` on View, Window, ScrollView, or TableView.
|
|
54
|
+
**Problem:** Base container elements don't support padding in Titanium.
|
|
55
|
+
**Solution:** Use margins on children instead:
|
|
56
|
+
```xml
|
|
57
|
+
<!-- WRONG -->
|
|
58
|
+
<View class="p-4">
|
|
59
|
+
<Label text="Hello" />
|
|
60
|
+
</View>
|
|
61
|
+
|
|
62
|
+
<!-- CORRECT -->
|
|
63
|
+
<View>
|
|
64
|
+
<Label class="m-4" text="Hello" />
|
|
65
|
+
</View>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 11. Confusing `w-full` with `w-screen`
|
|
69
|
+
**Symptom:** Using `w-full` when `w-screen` is needed.
|
|
70
|
+
**Difference:** `w-full` sets `width: '100%'` (100% of parent), while `w-screen` sets `width: Ti.UI.FILL` (fills available space).
|
|
71
|
+
**Solution:** Use `w-screen` for full-width elements that should fill space. `w-full` is useful when you need percentage-based sizing.
|
|
72
|
+
|
|
73
|
+
## 12. Using `rounded-full` Without Size
|
|
74
|
+
**Symptom:** Using `rounded-full` expecting a circle.
|
|
75
|
+
**Problem:** `rounded-full` (without number) doesn't exist. You need `rounded-full-XX` where XX × 4 = element size.
|
|
76
|
+
**Note:** `rounded-full-XX` already includes width and height. Don't add `w-XX h-XX` with it.
|
|
77
|
+
**Solution:** For a 48×48 circle, use `rounded-full-12` (includes size). For percentage-based, use `w-12 h-12 rounded-full`.
|
|
78
|
+
|
|
79
|
+
## 13. Adding `composite` Class Explicitly
|
|
80
|
+
**Symptom:** Adding `class="composite"` to Views.
|
|
81
|
+
**Problem:** Composite (absolute positioning) is the DEFAULT layout. Adding it is redundant.
|
|
82
|
+
**Solution:** Omit layout class for composite, only use `horizontal` or `vertical` when needed.
|
|
83
|
+
|
|
84
|
+
## 14. Square Brackets for Arbitrary Values
|
|
85
|
+
**Symptom:** Using `w-[100px]` or `bg-[#ff0000]` with square brackets.
|
|
86
|
+
**Problem:** PurgeTSS uses parentheses, not square brackets.
|
|
87
|
+
**Solution:** Use parentheses: `w-(100px)`, `bg-(#ff0000)`.
|
|
88
|
+
|
|
89
|
+
## 15. Creating Manual .tss Files Per Controller
|
|
90
|
+
**Symptom:** Creating `app/styles/login.tss`, `app/styles/profile.tss`, etc.
|
|
91
|
+
**Problem:** Defeats the purpose of PurgeTSS which auto-generates a single optimized `app.tss`.
|
|
92
|
+
**Solution:** Use ONLY utility classes in XML. Delete all manual `.tss` files except `_app.tss`.
|
|
93
|
+
|
|
94
|
+
## 16. Using `lib/` Prefix in Require Statements
|
|
95
|
+
**Symptom:** `const service = require('lib/services/picsum')`
|
|
96
|
+
**Problem:** Alloy flattens the `lib/` folder during build. Files in `app/lib/services/` become `Resources/iphone/services/`.
|
|
97
|
+
**Solution:** Omit the `lib/` prefix: `const service = require('services/picsum')`
|
|
98
|
+
|
|
99
|
+
## 17. Wrong Window ID in Controller
|
|
100
|
+
**Symptom:** Using `$.index.open()` when the Window has `id="mainWindow"`.
|
|
101
|
+
**Problem:** Alloy generates `$` references from XML IDs. If Window is `id="mainWindow"`, `$.index` doesn't exist.
|
|
102
|
+
**Solution:** Match the ID: `$.mainWindow.open()`
|
|
103
|
+
|
|
104
|
+
## 18. Using `Ti.UI.createNotification`
|
|
105
|
+
**Symptom:** `Ti.UI.createNotification({ message: 'Hi' }).show()`
|
|
106
|
+
**Problem:** This API doesn't exist in Titanium. Causes "invalid method" error.
|
|
107
|
+
**Solution:** Use `Ti.UI.createAlertDialog` for simple messages, or create custom toast views.
|
|
108
|
+
|
|
109
|
+
## 19. Using Nonexistent iOS Share APIs
|
|
110
|
+
**Symptom:** `Ti.UI.iOS.createActivityPopover` or `alloy/social` with wrong methods.
|
|
111
|
+
**Problem:** These APIs either don't exist or have changed. Causes runtime errors.
|
|
112
|
+
**Solution:**
|
|
113
|
+
- iOS: Use `Ti.UI.iOS.createDocumentViewer` for files, or simple `Ti.UI.createOptionDialog` + `Ti.UI.Clipboard` for links
|
|
114
|
+
- Android: Use `Ti.Android.createIntent` with ACTION_SEND
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Quick Reference Table
|
|
119
|
+
|
|
120
|
+
| Anti-Pattern | Why It Fails | Correct Approach |
|
|
121
|
+
| -------------------- | ------------------------ | ----------------------- |
|
|
122
|
+
| `flex-row` | Flexbox not supported | `horizontal` |
|
|
123
|
+
| `flex-col` | Flexbox not supported | `vertical` |
|
|
124
|
+
| `justify-*` | Flexbox not supported | Use margins/positioning |
|
|
125
|
+
| `p-4` on View | No padding on containers | `m-4` on children |
|
|
126
|
+
| `w-full` | Doesn't exist | `w-screen` |
|
|
127
|
+
| `rounded-full` | Needs size suffix | `rounded-full-12` |
|
|
128
|
+
| `composite` class | Already default | Omit it |
|
|
129
|
+
| `w-[100px]` | Wrong syntax | `w-(100px)` |
|
|
130
|
+
| Manual `.tss` | Overwritten by PurgeTSS | Use utility classes |
|
|
131
|
+
| `lib/` prefix | lib/ is flattened | Use path without lib/ |
|
|
132
|
+
| `$.index.open()` | Wrong ID reference | Use actual Window ID |
|
|
133
|
+
| `createNotification` | API doesn't exist | `createAlertDialog` |
|