Skip to content

Instantly share code, notes, and snippets.

@ggichure
Last active January 28, 2020 18:33
Show Gist options
  • Select an option

  • Save ggichure/565d44af75e48609803784da9e022c16 to your computer and use it in GitHub Desktop.

Select an option

Save ggichure/565d44af75e48609803784da9e022c16 to your computer and use it in GitHub Desktop.
class CameraThumb extends StatefulWidget {
const CameraThumb({Key key}) : super(key: key);
@override
CameraThumbState createState() => CameraThumbState();
}
class CameraThumbState extends State<CameraThumb>
with AutomaticKeepAliveClientMixin, SingleTickerProviderStateMixin {
CameraController _controller;
List<CameraDescription> _cameras;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
bool _isRecordingMode = false;
bool _isRecording = false;
// final _timerKey = GlobalKey<VideoTimerState>();
Future<void> _initCamera() async {
_cameras = await availableCameras();
_controller = CameraController(_cameras[0], ResolutionPreset.max);
_controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}
@override
void dispose() {
_controller?.dispose();
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
if (_controller != null) {
if (!_controller.value.isInitialized) {
return Container();
}
} else {
return const Center(
child: SizedBox(
width: 32,
height: 32,
child: CircularProgressIndicator(),
),
);
}
if (!_controller.value.isInitialized) {
return Container();
}
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
key: _scaffoldKey,
extendBody: true,
body: Stack(
children: <Widget>[
_buildCameraPreview(),
],
),
)
////////////
///
///
///
///
],
),
bottomNavigationBar: _buildBottomNavigationBar(),
);
}
;
}
Widget _buildCameraPreview() {
final size = MediaQuery.of(context).size;
return ClipRect(
child: Container(
child: Transform.scale(
scale: _controller.value.aspectRatio / size.aspectRatio,
child: Center(
child: AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: CameraPreview(_controller),
),
),
),
),
)
Widget _buildBottomNavigationBar() {
return Container(
color: Colors.transparent,
height: 100.0,
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
FutureBuilder(
future: getLastImage(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
width: 60.0,
height: 60.0,
);
}
return GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Gallery(),
),
),
child: Container(
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
border:
Border.all(color: Colors.purple[200], width: 2.0)),
width: 80.0,
height: 100.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(4.0),
child: Image.file(
snapshot.data,
fit: BoxFit.cover,
),
),
),
);
},
),
CircleAvatar(
backgroundColor: Colors.white,
radius: 28.0,
child: IconButton(
icon: Icon(
(_isRecordingMode)
? (_isRecording) ? Icons.stop : Icons.videocam
: Icons.camera_alt,
size: 28.0,
color: (_isRecording) ? Colors.red : Colors.black,
),
onPressed: () {
if (!_isRecordingMode) {
_captureImage();
} else {
if (_isRecording) {
stopVideoRecording();
} else {
startVideoRecording();
}
}
},
),
),
SizedBox(
width: 40,
),
/* IconButton(
icon: Icon(
(_isRecordingMode) ? Icons.camera_alt : Icons.videocam,
color: Colors.white,
),
onPressed: () {
setState(() {
_isRecordingMode = !_isRecordingMode;
});
},
),*/
],
),
);
}
Future<FileSystemEntity> getLastImage() async {
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/media';
final myDir = Directory(dirPath);
List<FileSystemEntity> _images;
_images = myDir.listSync(recursive: true, followLinks: false);
_images.sort((a, b) {
return b.path.compareTo(a.path);
});
var lastFile = _images[0];
var extension = path.extension(lastFile.path);
if (extension == '.jpeg') {
return lastFile;
} else {}
}
Future<void> _onCameraSwitch() async {
final CameraDescription cameraDescription =
(_controller.description == _cameras[0]) ? _cameras[1] : _cameras[0];
if (_controller != null) {
await _controller.dispose();
}
_controller = CameraController(cameraDescription, ResolutionPreset.medium);
_controller.addListener(() {
if (mounted) setState(() {});
if (_controller.value.hasError) {
showInSnackBar('Camera error ${_controller.value.errorDescription}');
}
});
try {
await _controller.initialize();
} on CameraException catch (e) {
_showCameraException(e);
}
if (mounted) {
setState(() {});
}
}
void _captureImage() async {
print('_captureImage');
if (_controller.value.isInitialized) {
SystemSound.play(SystemSoundType.click);
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/media';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${_timestamp()}.jpeg';
print('path: $filePath');
await _controller.takePicture(filePath);
setState(() {});
Navigator.of(context).pushNamed(/gallery);
}
}
Future<String> startVideoRecording() async {
print('startVideoRecording');
if (!_controller.value.isInitialized) {
return null;
}
setState(() {
_isRecording = true;
});
//_timerKey.currentState.startTimer();
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/media';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${_timestamp()}.mp4';
if (_controller.value.isRecordingVideo) {
// A recording is already started, do nothing.
return null;
}
try {
// videoPath = filePath;
await _controller.startVideoRecording(filePath);
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
return filePath;
}
Future<void> stopVideoRecording() async {
if (!_controller.value.isRecordingVideo) {
return null;
}
// _timerKey.currentState.stopTimer();
setState(() {
_isRecording = false;
});
try {
await _controller.stopVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
}
String _timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
void _showCameraException(CameraException e) {
logError(e.code, e.description);
showInSnackBar('Error: ${e.code}\n${e.description}');
}
void showInSnackBar(String message) {
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(message)));
}
void logError(String code, String message) =>
print('Error: $code\nError Message: $message');
@override
bool get wantKeepAlive => true;
}
class Gallery extends StatefulWidget {
@override
_GalleryState createState() => _GalleryState();
}
class _GalleryState extends State<Gallery> {
String currentFilePath;
String currentUser;
Firestore _fs = Firestore.instance;
RecordData recordData;
String imageName;
String imgUrl;
@override
void initState() {
super.initState();
getCurrentFirebaseUser();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: null,
body: FutureBuilder(
future: _getAllImages(),
builder: (context, AsyncSnapshot<List<FileSystemEntity>> snapshot) {
if (!snapshot.hasData || snapshot.data.isEmpty) {
return Container();
}
print('${snapshot.data.length} ${snapshot.data}');
if (snapshot.data.length == 0) {
return Center(
child: Text('No images found.'),
);
}
return PageView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
currentFilePath = snapshot.data[index].path;
var extension = path.extension(snapshot.data[index].path);
if (extension == '.jpeg') {
return Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * .94,
width: MediaQuery.of(context).size.width * 1,
padding: const EdgeInsets.only(bottom: 3.0),
child: Container(
child: Image.file(
File(snapshot.data[index].path),
fit: BoxFit.fill,
),
)),
],
);
} else {
return Center(
child: Text("no images found"),
);
}
},
);
},
),
bottomNavigationBar: BottomAppBar(
child: Container(
color: Colors.purple[200],
height: 56.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
/* IconButton(
icon: Icon(Icons.share),
onPressed: () => _shareFile(),
),*/
IconButton(
iconSize: 30,
icon: Icon(Icons.cancel),
onPressed: _deleteFile,
),
IconButton(
iconSize: 30,
icon: Icon(Icons.check),
onPressed: () {
var image = File(currentFilePath).readAsBytesSync();
uploadImageFs(image);
})
],
),
),
),
);
}
_shareFile() async {
var extension = path.extension(currentFilePath);
await Share.file(
'image',
(extension == '.jpeg') ? 'image.jpeg' : ' video.mp4',
File(currentFilePath).readAsBytesSync(),
(extension == '.jpeg') ? 'image/jpeg' : ' video/mp4',
);
// var image=File(currentFilePath).readAsBytesSync();
// uploadImageFs(image);
}
_deleteFile() {
final dir = Directory(currentFilePath);
dir.deleteSync(recursive: true);
print('deleted');
setState(() {});
}
Future<List<FileSystemEntity>> _getAllImages() async {
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/media';
final myDir = Directory(dirPath);
List<FileSystemEntity> _images;
_images = myDir.listSync(recursive: true, followLinks: false);
_images.sort((a, b) {
return b.path.compareTo(a.path);
});
return _images;
}
Future<FirebaseUser> getCurrentFirebaseUser() async {
FirebaseUser user = await FirebaseAuth.instance.currentUser();
currentUser = user.uid;
return user;
}
Future uploadImageFs(var asset) async {
setState(() {
imageName = DateTime.now().millisecondsSinceEpoch.toString();
});
final StorageReference storageReference = FirebaseStorage.instance
.ref()
.child("images")
.child("$currentUser/$imageName");
StorageUploadTask uploadTask = storageReference.putData(asset);
final StreamSubscription<StorageTaskEvent> streamSubscription =
uploadTask.events.listen((event) {
// You can use this to notify yourself or your user in any kind of way.
// For example: you could use the uploadTask.events stream in a StreamBuilder instead
// to show your user what the current status is. In that case, you would not need to cancel any
// subscription as StreamBuilder handles this automatically.
CircularProgressIndicator();
Fluttertoast.showToast(
msg: "Uploading...",
backgroundColor: Colors.green,
textColor: Colors.white,
toastLength: Toast.LENGTH_LONG,
timeInSecForIos: 2,
gravity: ToastGravity.BOTTOM);
// Here, every StorageTaskEvent concerning the upload is printed to the logs.
print('EVENT ${event.type}');
});
await uploadTask.onComplete;
streamSubscription.cancel();
String docUrl = await (await uploadTask.onComplete).ref.getDownloadURL();
setState(() {
imgUrl = docUrl;
});
DocumentReference doc = await Firestore.instance
.collection("users")
...
});
String recordId = doc.documentID.toString();
//save to url to firestore
_deleteFile();
Fluttertoast.showToast(msg: "done ");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment