Skip to content

Commit 0c59ef3

Browse files
feat: Webview Chatwoot Widget (#42)
* feat: add webview chatwoot widget * chore: upgrade gradle * chore: untrack generated files * chore: add path provider mock for tests * chore: update json identifier hash key * chore: deprecated chatwoot dialog widget * chore: updated sdk exports * fix: add close event trigger * feat: add widget callbacks * chore: update webview widget docs * chore: correct typos in dart docs variable description * docs: update README.md * docs: update README.md * Update example/lib/main.dart --------- Co-authored-by: Sivin Varghese <[email protected]>
1 parent 0f0f1f6 commit 0c59ef3

31 files changed

+1232
-1148
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
.buildlog/
99
.history
1010
.svn/
11+
*.g.dart
12+
*.mocks.dart
13+
applicationDocumentsPath
14+
hive_testing_path
1115

1216
# IntelliJ related
1317
*.iml

README.md

+87-107
Large diffs are not rendered by default.

example/android/app/build.gradle

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ apply plugin: 'kotlin-android'
2626
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
2727

2828
android {
29-
compileSdkVersion 30
29+
compileSdkVersion 33
3030

3131
sourceSets {
3232
main.java.srcDirs += 'src/main/kotlin'
3333
}
3434

3535
defaultConfig {
3636
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
37-
applicationId "com.example.example"
38-
minSdkVersion 16
39-
targetSdkVersion 30
37+
applicationId "com.chatwoot.example"
38+
minSdkVersion 19
39+
targetSdkVersion 33
4040
versionCode flutterVersionCode.toInteger()
4141
versionName flutterVersionName
4242
}

example/android/app/src/main/AndroidManifest.xml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
android:theme="@style/LaunchTheme"
1010
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
1111
android:hardwareAccelerated="true"
12+
android:exported="true"
1213
android:windowSoftInputMode="adjustResize">
1314
<!-- Specifies an Android theme to apply to this Activity as soon as
1415
the Android process has started. This theme is visible to the user

example/android/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
buildscript {
2-
ext.kotlin_version = '1.3.50'
2+
ext.kotlin_version = '1.7.20'
33
repositories {
44
google()
55
jcenter()
66
}
77

88
dependencies {
9-
classpath 'com.android.tools.build:gradle:4.1.0'
9+
classpath 'com.android.tools.build:gradle:7.4.1'
1010
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1111
}
1212
}

example/android/gradle/wrapper/gradle-wrapper.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip

example/lib/main.dart

+58-61
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
import 'dart:io';
2+
13
import 'package:chatwoot_sdk/chatwoot_sdk.dart';
24
import 'package:flutter/material.dart';
5+
import 'package:flutter/services.dart';
6+
import 'package:image/image.dart' as image;
7+
import 'package:image_picker/image_picker.dart' as image_picker;
8+
import 'package:path_provider/path_provider.dart';
39

410
void main() {
511
runApp(MyApp());
@@ -31,75 +37,66 @@ class MyHomePage extends StatefulWidget {
3137
class _MyHomePageState extends State<MyHomePage> {
3238
@override
3339
void initState() {
34-
// TODO: implement initState
3540
super.initState();
3641
}
3742

38-
_showChatwootDialog() {
39-
ChatwootChatDialog.show(
40-
context,
41-
baseUrl: "https://app.chatwoot.com",
42-
inboxIdentifier: "xxxxxxxxxxxxxxxxxxx",
43-
title: "Chatwoot Support",
44-
user: ChatwootUser(
45-
identifier: "[email protected]",
46-
name: "Tester test",
47-
48-
),
49-
);
50-
}
51-
5243
@override
5344
Widget build(BuildContext context) {
54-
return ChatwootChat(
55-
baseUrl: "https://app.chatwoot.com",
56-
inboxIdentifier: "xxxxxxxxxxxxxxxxxxx",
57-
user: ChatwootUser(
58-
identifier: "[email protected]",
59-
name: "Tester test1",
60-
61-
),
45+
return Scaffold(
6246
appBar: AppBar(
63-
title: Text(
64-
"Chatwoot",
65-
style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
66-
),
67-
leading: InkWell(
68-
onTap: () => _showChatwootDialog(),
69-
child: Padding(
70-
padding: const EdgeInsets.all(8.0),
71-
child: Image.asset("assets/chatwoot_logo.png"),
72-
),
47+
title: Text("Chatwoot Example"),
48+
),
49+
body: ChatwootWidget(
50+
websiteToken: "websiteToken",
51+
baseUrl: "https://app.chatwoot.com",
52+
user: ChatwootUser(
53+
identifier: "[email protected]",
54+
name: "Tester test",
55+
7356
),
74-
backgroundColor: Colors.white,
57+
locale: "en",
58+
closeWidget: () {
59+
if (Platform.isAndroid) {
60+
SystemNavigator.pop();
61+
} else if (Platform.isIOS) {
62+
exit(0);
63+
}
64+
},
65+
//attachment only works on android for now
66+
onAttachFile: _androidFilePicker,
67+
onLoadStarted: () {
68+
print("loading widget");
69+
},
70+
onLoadProgress: (int progress) {
71+
print("loading... ${progress}");
72+
},
73+
onLoadCompleted: () {
74+
print("widget loaded");
75+
},
7576
),
76-
onWelcome: () {
77-
print("Welcome event received");
78-
},
79-
onPing: () {
80-
print("Ping event received");
81-
},
82-
onConfirmedSubscription: () {
83-
print("Confirmation event received");
84-
},
85-
onMessageDelivered: (_) {
86-
print("Message delivered event received");
87-
},
88-
onMessageSent: (_) {
89-
print("Message sent event received");
90-
},
91-
onConversationIsOffline: () {
92-
print("Conversation is offline event received");
93-
},
94-
onConversationIsOnline: () {
95-
print("Conversation is online event received");
96-
},
97-
onConversationStoppedTyping: () {
98-
print("Conversation stopped typing event received");
99-
},
100-
onConversationStartedTyping: () {
101-
print("Conversation started typing event received");
102-
},
10377
);
10478
}
79+
80+
Future<List<String>> _androidFilePicker() async {
81+
final picker = image_picker.ImagePicker();
82+
final photo =
83+
await picker.pickImage(source: image_picker.ImageSource.gallery);
84+
85+
if (photo == null) {
86+
return [];
87+
}
88+
89+
final imageData = await photo.readAsBytes();
90+
final decodedImage = image.decodeImage(imageData);
91+
final scaledImage = image.copyResize(decodedImage, width: 500);
92+
final jpg = image.encodeJpg(scaledImage, quality: 90);
93+
94+
final filePath = (await getTemporaryDirectory()).uri.resolve(
95+
'./image_${DateTime.now().microsecondsSinceEpoch}.jpg',
96+
);
97+
final file = await File.fromUri(filePath).create(recursive: true);
98+
await file.writeAsBytes(jpg, flush: true);
99+
100+
return [file.uri.toString()];
101+
}
105102
}

0 commit comments

Comments
 (0)