File size: 5,859 Bytes
f3d0444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// do not compress more than declared below, otherwise canvas will be blank
// https://github.com/jhildenbiddle/canvas-size
var maxCanvasWidth = 4096, maxCanvasHeight = 4096;
// accepted file type on uploading
var acceptedFileType = ['jpg', 'jpeg', 'png'];
// compressor options, for compressing captured and uploaded image
Compressor.setDefaults({
    mimeType: 'image/png',
    maxWidth: 1050,
    maxHeight: 800,
    convertSize: 2000000,
});
// croppie options, for scaling and rotating captured and uploaded image
// original calculation, calculate from `form-ocr` width
// var scale = 1.33 // get from `640 / 480` desktop video size
//     , boundaryWidth = $('#form-ocr').width()
//     , boundaryHeight = Math.floor(boundaryWidth / scale)
//     , viewportWidth = boundaryHeight
//     , viewportHeight = Math.floor(viewportWidth / scale);
var croppieOpts = {
    viewport: { width: 340, height: 240 },
    boundary: { width: screen.width, height: 525 },
    showZoomer: false,
    enableOrientation: true,
};
$('#img-preview').croppie(croppieOpts); // init croppie to element, use `bind` to add image data
window.addEventListener("flutterInAppWebViewPlatformReady", null); // add event to send message to app


// file change
$('.file-capture, .file-upload').change(function() {
    var file = event.target.files[0]
        , isInitial = $('.croppie-container #text-preview').length == 0;

    if (file === undefined) modalAlert(gettext('Invalid Image'), gettext('No image file selected'));
    if (!validateFileType($(this).val())) modalAlert(gettext('Invalid Image'), gettext('Please upload valid identification in JPEG/PNG format'));
    new Compressor(file, {
        success: function(result) {
            blobToDataURL(result, function(dataURL) {
                $('#img-preview').croppie('bind', dataURL).then(function() { // update image data
                    $('#img-preview').croppie('setZoom', 0); // change zoom level
                });
                if (isInitial) { // will not init if re-upload or re-take
                    initCroppieComponents();
                    initBorderGuide();
                }
            });
        },
        error: function(err) {
            console.error('Compressor() error:'+ err.message);
            modalAlert(gettext('Error'), gettext('Error capturing image'));
        },
    });
});


// btn-next click
$('#btn-next').click(function() {
    var $img = $('#img-preview')
        , $ocrFile = $('#id_ocr_file')
        , dataURL;
        
    // disable all button
    $('.btn').attr('disabled', true).addClass('disabled');

    $img.croppie('result', {
        'type': 'rawcanvas',
        'size': 'original',
        'format': 'png',
    }).then(function(canvas) {
        dataURL = canvas.toDataURL();
        $ocrFile.val(dataURL.substring(22)); // remove `data:image/png;base64,` on dataURL
        $('#form-ocr').submit();
    });
});


$('#btn-back').click(function() {
    try { window.flutter_inappwebview.callHandler('backToMobile', 'true'); } catch(error) {}
});


// validate file type
function validateFileType(fileName) {
    var splited = fileName.split('.')
        , fileType = (splited[splited.length - 1]).toLowerCase();
    if ((!fileName) || (splited.length <= 1) || (acceptedFileType.indexOf(fileType) < 0)) return false;
    return true;
}


// blob to dataURL
function blobToDataURL(blob, callback) {
    var reader = new FileReader();
    reader.onload = function(e) { callback(e.target.result); }
    reader.readAsDataURL(blob);
}


// dataURL to blob
function dataURLtoBlob(dataURL) {
    var arr = dataURL.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}


// initiate croppie components, ie: moving timer, add rotate button, etc
function initCroppieComponents() {
    var $timer = $('.timer-text').clone().removeClass('text-secondary').addClass('text-white')
        , $previewText = $('<div></div>').addClass('text-white').attr('id', 'text-preview').html(gettext('Drag, rotate, or pinch the image to make sure<br>that all information is within the box.'))
        , $iconRotate = $('<span></span>').addClass('material-icons-outlined').text('rotate_90_degrees_ccw')
        , $btnRotate = $('<button></button>').attr('type', 'button').addClass('btn btn-dark').attr('id', 'btn-rotate').data('degree', 90).html($iconRotate).click(function () {
            $('#img-preview').croppie('rotate', $(this).data('degree'));
        })
        , $rotateContainer = $('<div></div>').attr('id', 'rotate-container').append($btnRotate);

    $('header, .page-header, .page-subheader, .default-container').hide();
    $('main').addClass('no-header');
    $('.preview-container').show();
    $('.cr-boundary').append($timer, $previewText, $rotateContainer);
}


// initiate border guide on croppie view port
function initBorderGuide() {
    var guideTopRight1 = $('<div></div>').addClass('guide-top-right-1')
        , guideTopRight2 = $('<div></div>').addClass('guide-top-right-2')
        , guideBottomRight1 = $('<div></div>').addClass('guide-bottom-right-1')
        , guideBottomRight2 = $('<div></div>').addClass('guide-bottom-right-2')
        , guideTopLeft1 = $('<div></div>').addClass('guide-top-left-1')
        , guideTopLeft2 = $('<div></div>').addClass('guide-top-left-2')
        , guideBottomLeft1 = $('<div></div>').addClass('guide-bottom-left-1')
        , guideBottomLeft2 = $('<div></div>').addClass('guide-bottom-left-2')

    $('.cr-boundary .cr-viewport').append(
        guideTopRight1,
        guideTopRight2,
        guideBottomRight1,
        guideBottomRight2,
        guideTopLeft1,
        guideTopLeft2,
        guideBottomLeft1,
        guideBottomLeft2
    );
}