Fakultas Ilmu Komputer UI

dashboard.dart 10.9 KB
Newer Older
1
import 'package:bisaGo/bloc/lokasi_response_bloc.dart';
2
import 'package:bisaGo/model/komentar.dart';
3
4
import 'package:bisaGo/model/lokasi.dart';
import 'package:bisaGo/network/data/network_model.dart';
5
6
import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart';
import 'package:bisaGo/repository/komentar_repository.dart';
7
import 'package:bisaGo/utils/custom_dashboard_location_button.dart';
8
import 'package:bisaGo/utils/location_turn_on_dialog.dart';
9
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
10
import 'package:flutter/material.dart';
11
import 'package:flutter_dotenv/flutter_dotenv.dart';
12
import 'package:geolocator/geolocator.dart';
13
import 'package:google_maps_flutter/google_maps_flutter.dart';
14
15
16
17
import 'package:bisaGo/component/bisago_appbar.dart';
import 'package:bisaGo/component/bisago_drawer.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/page/pencarian/pencarian.dart';
18
import 'package:google_maps_webservice/places.dart';
19
20

class Dashboard extends StatefulWidget {
21
  const Dashboard({Key key}) : super(key: key);
22
  @override
23
24
25
26
  DashboardState createState() => DashboardState();
}

class DashboardState extends State<Dashboard> {
Fakhira Devina's avatar
Fakhira Devina committed
27
  final double cameraZoom = 15;
28
29
30
  GoogleMapController mapController;
  Geolocator geolocator;
  LatLng currentLocation;
31
  Set<Marker> markers = {};
32

33
34
  LokasiResponseBloc bloc = LokasiResponseBloc();

35
36
37
  @override
  void initState() {
    super.initState();
38
    _showTurnOnLocationDialog(context);
39
    geolocator = Geolocator()..forceAndroidLocationManager;
40
    initDynamicLinks();
41
    setInitialLocation();
42
43
  }

44
  void _navigateToPencarianPage(BuildContext context) {
45
    final route = MaterialPageRoute(builder: (_) => const Pencarian());
46
47
48
    Navigator.of(context).push(route);
  }

49
50
51
52
  // void _navigateToInformasiLayananDisabilitasPage(BuildContext context) {
  //   final route = MaterialPageRoute(builder: (_) => ListSekolah());
  //   Navigator.of(context).push(route);
  // }
53

54
  static const textFieldKey = Key('Text Field Mau Kemana');
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

  void _showTurnOnLocationDialog(BuildContext context) {
    bloc.isLocationServiceTurnedOn().then(
      (value) {
        if (!value) {
          showDialog(
            context: context,
            builder: (BuildContext context) {
              return LocationTurnOnDialog(
                message: 'Mohon Menyalakan Lokasi',
                title: 'Lokasi',
                onPressed: () {
                  bloc.requestLocationService().then((loc) {
                    if (loc) {
                      Navigator.pop(context);
                    }
                  });
                },
              );
            },
          );
        }
      },
    );
  }

81
82
83
  @override
  Widget build(BuildContext context) {
    return Scaffold(
84
      drawer: BisaGoDrawer(),
85
86
87
88
89
90
91
92
93
94
95
96
      body: Stack(
        key: const Key('Stack'),
        alignment: AlignmentDirectional.bottomStart,
        children: <Widget>[
          _buildGoogleMap(context),
          Container(
            height: 285,
            alignment: Alignment.bottomCenter,
            decoration: const BoxDecoration(
              color: white,
              borderRadius: BorderRadius.all(
                Radius.circular(10.0),
97
              ),
98
            ),
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
            padding: const EdgeInsets.symmetric(
                horizontal: doubleSpace, vertical: doubleSpace),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                InkWell(
                  key: const Key('Navigate to Pencarian'),
                  onTap: () => _navigateToPencarianPage(context),
                  child: Container(
                    key: const Key('Container Text Field'),
                    padding: EdgeInsets.zero,
                    decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: regularBorderRadius,
                        border: Border.all(color: greenPrimary),
                        boxShadow: regularShadow),
                    child: TextFormField(
                      enabled: false,
                      key: const Key('Text Field Mau Kemana'),
119
                      decoration: const InputDecoration(
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
                        prefixIcon: Icon(
                          Icons.search,
                          color: greenPrimary,
                          size: 25,
                        ),
                        border: InputBorder.none,
                        fillColor: Colors.white,
                        labelText: 'Tekan untuk mencari tempat',
                        labelStyle: TextStyle(
                            color: greenPrimary,
                            fontSize: 20,
                            fontFamily: 'Muli',
                            fontWeight: FontWeight.w700),
                      ),
                    ),
                  ),
                ),
137
                const SizedBox(height: doubleSpace),
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
                const Text(
                  'Paling sering dicari',
                  style: TextStyle(
                    color: Colors.black,
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(height: 10),
                StreamBuilder<NetworkModel<LokasiListResponse>>(
                    stream: bloc.lokasiListStream,
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        switch (snapshot.data.status) {
                          case Status.loading:
                            return Container(
                              height: 130,
155
156
                              child: const Center(
                                child: CircularProgressIndicator(
157
158
159
160
161
162
163
                                  valueColor: AlwaysStoppedAnimation<Color>(
                                      greenPrimary),
                                ),
                              ),
                            );
                            break;
                          case Status.completed:
Jovi Handono Hutama's avatar
Jovi Handono Hutama committed
164
                            final places = snapshot.data.data.listLokasi;
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
                            return _buildLokasiWidget(places);
                            break;
                          case Status.error:
                            return Container(
                              height: 130,
                              child: const Center(
                                child: Text('Gagal untuk mendapatkan tempat'),
                              ),
                            );
                            break;
                        }
                        return Container();
                      }
                      return Container();
                    }),
              ],
            ),
182
          ),
183
        ],
184
      ),
185
186
187
188
189
190
191
192
193
194
      // floatingActionButton: FloatingActionButton.extended(
      //   key: const Key('FloatingActionButton'),
      //   onPressed: () {
      //     _navigateToInformasiLayananDisabilitasPage(context);
      //   },
      //   label: Text('Informasi Layanan Disabilitas'),
      //   icon: Icon(Icons.search),
      //   backgroundColor: greenPrimary,
      // ),
      // floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
195
196
197
      appBar: const PreferredSize(
        preferredSize: Size.fromHeight(55),
        key: Key('Scaffold Text Field'),
198
        child: BisaGoAppBar(),
Agnes Handoko's avatar
Agnes Handoko committed
199
      ),
200
201
202
    );
  }

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
  Widget _buildLokasiWidget(List<Lokasi> lokasilistresponse) {
    return Container(
      height: 130,
      child: ListView(
        scrollDirection: Axis.horizontal,
        children: [
          Row(
              children: lokasilistresponse
                  .map<Widget>((k) => LocationIconButton(
                        location: k,
                      ))
                  .toList()),
        ],
      ),
    );
  }

220
  Widget _buildGoogleMap(BuildContext context) {
221
    if (currentLocation == null) {
222
      return const Center(
223
        child: CircularProgressIndicator(),
224
      );
225
226
227
228
    } else {
      return GoogleMap(
        initialCameraPosition:
            CameraPosition(target: currentLocation, zoom: cameraZoom),
229
        onMapCreated: (GoogleMapController controller) {
230
          mapController = controller;
231
        },
232
        myLocationEnabled: true,
233
        markers: markers,
234
235
236
        onCameraMove: _onCameraMove,
      );
    }
237
238
  }

239
  void _onCameraMove(CameraPosition position) {
240
    setState(() {
241
      currentLocation = position.target;
242
243
244
    });
  }

245
  void setInitialLocation() async {
246
    final position = await geolocator.getCurrentPosition(
247
248
249
250
251
        desiredAccuracy: LocationAccuracy.high);

    setState(() {
      currentLocation = LatLng(position.latitude, position.longitude);
    });
252
  }
253
254
255
256
257
258
259
260
261
262
263
264

  Future<String> getLokasiName(String placeId) async {
    final _places = GoogleMapsPlaces(apiKey: DotEnv().env['API_KEY']);
    var details = await _places.getDetailsByPlaceId(
      placeId,
      fields: [
        'name',
      ],
    );
    return details.result.name;
  }

265
266
  void _navigateToDetailFasilitasPage(
      BuildContext context, String placeId, String fasilitasId) async {
267
268
269
270
271
272
273
274
275
    final fetches = await Future.wait([
      KomentarRepository().fetchDetailFasilitas(placeId, fasilitasId),
      getLokasiName(placeId),
    ]);
    final KomentarModel fasilitas = fetches[0];
    final String namaLokasi = fetches[1] ?? 'INVALID';
    final lokasi = Lokasi()
      ..placeId = placeId
      ..name = namaLokasi;
276
    final fasilitasRoute = MaterialPageRoute(
277
        builder: (BuildContext context) => DetailPostPage(
278
279
280
281
282
283
284
285
286
287
288
289
290
291
              lokasi: lokasi,
              komentar: KomentarModel(
                creator: fasilitas.creator,
                dateTime: fasilitas.dateTime,
                deskripsi: fasilitas.deskripsi,
                id: fasilitas.id,
                image: fasilitas.image,
                isVerified: fasilitas.isVerified,
                namaLokasi: lokasi.name,
                tag: fasilitas.tag,
                disabilitas: fasilitas.disabilitas,
                jumlah: fasilitas.jumlah,
              ),
            ));
292
    await Navigator.of(context).push(fasilitasRoute);
293
  }
294

295
296
  void initDynamicLinks() async {
    final data = await FirebaseDynamicLinks.instance.getInitialLink();
297

298
299
300
    _handleDeepLink(data);
    FirebaseDynamicLinks.instance.onLink(
        onSuccess: (PendingDynamicLinkData dynamicLink) async {
301
302
303
      _handleDeepLink(dynamicLink);
    }, onError: (OnLinkErrorException e) async {
      print('Link Failed: ${e.message}');
304
305
    });
  }
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

  void _handleDeepLink(PendingDynamicLinkData data) async {
    final deepLink = data?.link;
    if (deepLink != null) {
      final params = deepLink.queryParameters;
      final path = deepLink.pathSegments;
      final placeId = params['place_id'];
      final id = params['id'];
      if (path[0] == 'fasilitas') {
        _navigateToDetailFasilitasPage(context, placeId, id);
      } else if (path[0] == 'kegiatan') {
        // TODO navigate kegiatan
      }
    }
  }
321
}