Merge branch 'master' into development_haroon

merge-requests/73/head
haroon amjad 3 years ago
commit ff0c1e1efc

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="35.227" height="30.23" viewBox="0 0 35.227 30.23">
<g id="Group_8914" data-name="Group 8914" transform="translate(-436.281 -27.777)">
<path id="Subtraction_63" data-name="Subtraction 63" d="M17162.83,16706.23h-19.455a1.373,1.373,0,1,1,0-2.746h16.879a9.989,9.989,0,0,0,2.572,2.744Zm-3.047-3.574h-14.691a1.373,1.373,0,1,1,0-2.746h.344v-12.369h-.344a.688.688,0,0,1,0-1.375h24.049a.688.688,0,0,1,0,1.375h-.346v.682h-.125a10,10,0,0,0-2.621.348v-1.029h-4.121v3.313a9.986,9.986,0,0,0-2.752,4.328v-7.641h-4.121v12.369h3.816a9.9,9.9,0,0,0,.91,2.744Zm-11.6-15.117v12.371h4.125v-12.369h-4.125Zm22.689-2.605h-27.5a1.376,1.376,0,0,1-.564-2.631l13.74-6.182a1.4,1.4,0,0,1,.566-.121,1.375,1.375,0,0,1,.563.121l13.637,6.135a1.376,1.376,0,0,1-.443,2.678Z" transform="translate(-16705.719 -16648.223)" fill="#125765"/>
<path id="Subtraction_64" data-name="Subtraction 64" d="M17150.225,16692.445a8.223,8.223,0,1,1,8.221-8.221A8.232,8.232,0,0,1,17150.225,16692.445Zm-2-4.574v0c.113.055.266.115.369.156l.078.031c.088.035.18.072.254.107v.5a.426.426,0,0,0,.4.4h1.7a.426.426,0,0,0,.4-.4v-.5c.1-.049.229-.1.342-.145s.246-.1.355-.152l.3.3a.375.375,0,0,0,.6,0l1.2-1.2a.372.372,0,0,0,0-.6l-.2-.1c.049-.1.1-.229.145-.332a3.748,3.748,0,0,1,.158-.365h.5a.43.43,0,0,0,.395-.4v-1.7a.43.43,0,0,0-.395-.4h-.5c-.045-.088-.09-.2-.135-.3l-.023-.061-.006-.012c-.045-.113-.092-.23-.139-.322l.3-.3a.375.375,0,0,0,0-.6l-1.2-1.2a.375.375,0,0,0-.6,0l-.3.3c-.094-.047-.209-.092-.32-.137l-.041-.018c-.125-.049-.246-.1-.342-.143v-.5a.426.426,0,0,0-.4-.4h-1.7a.426.426,0,0,0-.4.4v.5c-.1.047-.211.092-.342.143l-.041.018c-.111.045-.229.09-.32.137l-.3-.3c-.2-.3-.3-.3-.4-.3a.362.362,0,0,0-.3.1l-1.2,1.2a.379.379,0,0,0,0,.6l.3.3c-.049.1-.1.221-.154.357-.045.113-.1.24-.146.344h-.5a.428.428,0,0,0-.4.4v1.7a.426.426,0,0,0,.4.4h.5c.037.078.076.172.113.262l.031.078.006.012c.049.123.1.252.15.352l-.3.3a.375.375,0,0,0,0,.6l1.2,1.2a.483.483,0,0,0,.6,0l.3-.295Zm2-1.3a2.262,2.262,0,1,1,1.637-.662A2.276,2.276,0,0,1,17150.221,16686.57Z" transform="translate(-16686.938 -16634.438)" fill="#2bb8a6"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.277" height="20.393" viewBox="0 0 25.277 20.393">
<g id="certificate_1_" data-name="certificate (1)" transform="translate(0 -87.994)">
<g id="Group_8918" data-name="Group 8918" transform="translate(0 87.994)">
<g id="Group_8917" data-name="Group 8917" transform="translate(0 0)">
<path id="Path_14069" data-name="Path 14069" d="M0,89.39v15.7a1.388,1.388,0,0,0,1.388,1.388H16.832v-2.754a4.128,4.128,0,1,1,6.247,0v2.754h.81a1.388,1.388,0,0,0,1.388-1.388V94.445H20.5a1.667,1.667,0,0,1-1.665-1.665V88H1.388A1.388,1.388,0,0,0,0,89.39Zm3.081,2.967H16.94v1.526H3.081Zm0,5.46h11.75v.833H3.081Zm0,2.609H10.01v.833H3.081v-.833Z" transform="translate(0 -88.002)" fill="#125765"/>
<path id="Path_14070" data-name="Path 14070" d="M708.627,88.125v4.648a.833.833,0,0,0,.833.833h4.778l-5.611-5.611Z" transform="translate(-688.961 -87.994)" fill="#125765"/>
<path id="Path_14071" data-name="Path 14071" d="M641.121,683.129v-2.018a4.123,4.123,0,0,1-4.582,0v3.933l2.291-.912,2.291.912v-1.914Z" transform="translate(-618.874 -664.651)" fill="#2bb8a6"/>
<path id="Path_14072" data-name="Path 14072" d="M606.407,443.907a3.3,3.3,0,1,0-5.414,0,3.317,3.317,0,0,0,.416.49,3.295,3.295,0,0,0,5-.49Z" transform="translate(-583.744 -429.003)" fill="#2bb8a6"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="35.094" height="31.653" viewBox="0 0 35.094 31.653">
<g id="Group_8912" data-name="Group 8912" transform="translate(-324.415 -26.354)">
<g id="Group_8647" data-name="Group 8647" transform="translate(254.475 -869.609)">
<path id="Subtraction_55" data-name="Subtraction 55" d="M19.894,28.793H18.009a.845.845,0,0,1-.844-.843V21.173a1.417,1.417,0,0,0-1.415-1.416H13.039a1.417,1.417,0,0,0-1.415,1.416V27.95a.845.845,0,0,1-.844.843h-4.6a3.106,3.106,0,0,1-3.1-3.1V17.047H2.615c-.027,0-.055,0-.082,0A2.65,2.65,0,0,1,.769,12.527l.007-.007,0,0L12.52.776a2.65,2.65,0,0,1,3.749,0L28.014,12.522a2.645,2.645,0,0,1,.76,2.16,9.94,9.94,0,0,0-1.75-.155,8.994,8.994,0,0,0-6.355,2.483,9.044,9.044,0,0,0-.776,11.781Z" transform="translate(69.94 895.963)" fill="#125765"/>
</g>
<path id="Path_14064" data-name="Path 14064" d="M9.082,242a8.082,8.082,0,1,0,8.082,8.082A8.091,8.091,0,0,0,9.082,242Zm-.5,7.184h1a1.9,1.9,0,0,1,1.9,1.9v1a1.9,1.9,0,0,1-1.5,1.853v.342a.9.9,0,0,1-1.8,0v-.342a1.9,1.9,0,0,1-1.5-1.853.9.9,0,1,1,1.8,0,.1.1,0,0,0,.1.1h1a.1.1,0,0,0,.1-.1v-1a.1.1,0,0,0-.1-.1h-1a1.9,1.9,0,0,1-1.9-1.9v-1a1.9,1.9,0,0,1,1.5-1.853v-.342a.9.9,0,0,1,1.8,0v.342a1.9,1.9,0,0,1,1.5,1.853.9.9,0,0,1-1.8,0,.1.1,0,0,0-.1-.1h-1a.1.1,0,0,0-.1.1v1A.1.1,0,0,0,8.583,249.184Z" transform="translate(342.346 -200.156)" fill="#2bb8a6"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30.491" height="31.183" viewBox="0 0 30.491 31.183">
<g id="calendar_3_" data-name="calendar (3)" transform="translate(-5.411 -1)">
<g id="Group_7900" data-name="Group 7900" transform="translate(5.411 1)">
<path id="Path_4715" data-name="Path 4715" d="M120.92,258.949a.707.707,0,0,0-.708-.707h-2.47a.707.707,0,0,0-.707.707v2.47a.708.708,0,0,0,.707.708h2.47a.708.708,0,0,0,.708-.708v-2.47Z" transform="translate(-109.905 -241.746)" fill="#2bb8a6"/>
<path id="Path_4716" data-name="Path 4716" d="M217.555,258.949a.707.707,0,0,0-.707-.707h-2.47a.707.707,0,0,0-.707.707v2.47a.708.708,0,0,0,.707.708h2.47a.707.707,0,0,0,.707-.708Z" transform="translate(-200.367 -241.746)" fill="#2bb8a6"/>
<path id="Path_4717" data-name="Path 4717" d="M314.183,258.949a.707.707,0,0,0-.707-.707h-2.47a.707.707,0,0,0-.708.707v2.47a.708.708,0,0,0,.708.708h2.47a.708.708,0,0,0,.707-.708Z" transform="translate(-290.822 -241.746)" fill="#2bb8a6"/>
<path id="Path_4718" data-name="Path 4718" d="M120.92,355.582a.707.707,0,0,0-.708-.707h-2.47a.707.707,0,0,0-.707.707v2.469a.707.707,0,0,0,.707.707h2.47a.707.707,0,0,0,.708-.707v-2.469Z" transform="translate(-109.905 -332.206)" fill="#2bb8a6"/>
<path id="Path_4719" data-name="Path 4719" d="M217.555,355.582a.707.707,0,0,0-.707-.707h-2.47a.707.707,0,0,0-.707.707v2.469a.707.707,0,0,0,.707.707h2.47a.707.707,0,0,0,.707-.707Z" transform="translate(-200.367 -332.206)" fill="#2bb8a6"/>
<path id="Path_4720" data-name="Path 4720" d="M314.183,355.582a.707.707,0,0,0-.707-.707h-2.47a.707.707,0,0,0-.708.707v2.469a.707.707,0,0,0,.708.707h2.47a.707.707,0,0,0,.707-.707v-2.469Z" transform="translate(-290.822 -332.206)" fill="#2bb8a6"/>
<path id="Path_4721" data-name="Path 4721" d="M33.188,54.156v3.772A3.081,3.081,0,0,1,30.1,61.006H28.153a3.1,3.1,0,0,1-3.106-3.079V54.142h-8.78v3.786a3.1,3.1,0,0,1-3.106,3.079H11.213a3.081,3.081,0,0,1-3.088-3.079V54.156a2.808,2.808,0,0,0-2.714,2.793V79.055a2.809,2.809,0,0,0,2.8,2.812h24.9a2.812,2.812,0,0,0,2.8-2.812V56.949A2.808,2.808,0,0,0,33.188,54.156Zm-.9,23.522a1.208,1.208,0,0,1-1.208,1.208H10.185a1.208,1.208,0,0,1-1.208-1.208V66.259a1.208,1.208,0,0,1,1.208-1.209h20.89a1.209,1.209,0,0,1,1.208,1.209V77.678Z" transform="translate(-5.411 -50.683)" fill="#125765"/>
<path id="Path_4722" data-name="Path 4722" d="M80.609,8.3h1.927a1.058,1.058,0,0,0,1.059-1.058V1.059A1.059,1.059,0,0,0,82.536,0H80.609A1.059,1.059,0,0,0,79.55,1.059V7.242A1.058,1.058,0,0,0,80.609,8.3Z" transform="translate(-74.814)" fill="#125765"/>
<path id="Path_4723" data-name="Path 4723" d="M345.517,8.3h1.927A1.058,1.058,0,0,0,348.5,7.242V1.059A1.059,1.059,0,0,0,347.444,0h-1.927a1.059,1.059,0,0,0-1.059,1.059V7.242A1.058,1.058,0,0,0,345.517,8.3Z" transform="translate(-322.8)" fill="#125765"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30.492" height="31.341" viewBox="0 0 30.492 31.341">
<g id="calendar_3_" data-name="calendar (3)" transform="translate(-5.411 -1)">
<g id="Group_7900" data-name="Group 7900" transform="translate(5.411 1)">
<path id="Path_4715" data-name="Path 4715" d="M120.55,258.882a.64.64,0,0,0-.64-.64h-2.234a.64.64,0,0,0-.64.64v2.234a.64.64,0,0,0,.64.64h2.234a.64.64,0,0,0,.64-.64v-2.234Z" transform="translate(-110.585 -243.318)" fill="#125765"/>
<path id="Path_4716" data-name="Path 4716" d="M217.184,258.882a.64.64,0,0,0-.64-.64H214.31a.64.64,0,0,0-.64.64v2.234a.64.64,0,0,0,.64.64h2.235a.64.64,0,0,0,.64-.64Z" transform="translate(-201.635 -243.318)" fill="#125765"/>
<path id="Path_14060" data-name="Path 14060" d="M217.184,258.882a.64.64,0,0,0-.64-.64H214.31a.64.64,0,0,0-.64.64v2.234a.64.64,0,0,0,.64.64h2.235a.64.64,0,0,0,.64-.64Z" transform="translate(-196.052 -243.318)" fill="#125765"/>
<path id="Path_14059" data-name="Path 14059" d="M217.184,258.882a.64.64,0,0,0-.64-.64H214.31a.64.64,0,0,0-.64.64v2.234a.64.64,0,0,0,.64.64h2.235a.64.64,0,0,0,.64-.64Z" transform="translate(-201.635 -237.733)" fill="#125765"/>
<path id="Path_4718" data-name="Path 4718" d="M120.55,355.515a.64.64,0,0,0-.64-.64h-2.234a.64.64,0,0,0-.64.64v2.234a.64.64,0,0,0,.64.64h2.234a.64.64,0,0,0,.64-.64v-2.234Z" transform="translate(-110.585 -334.367)" fill="#125765"/>
<path id="Subtraction_61" data-name="Subtraction 61" d="M17.639,25.082H2.529A2.539,2.539,0,0,1,0,22.539v-20A2.547,2.547,0,0,1,2.455.015V3.426A2.791,2.791,0,0,0,5.249,6.21H7.013A2.8,2.8,0,0,0,9.821,3.426V0h7.943V3.426A2.8,2.8,0,0,0,20.572,6.21h1.763A2.791,2.791,0,0,0,25.13,3.426V.015a2.548,2.548,0,0,1,2.455,2.524V14.386H24.308V10.962a1.092,1.092,0,0,0-1.089-1.093H4.318a1.1,1.1,0,0,0-1.094,1.093V21.295a1.094,1.094,0,0,0,1.094,1.093H17.639v2.694Z" transform="translate(0 3.127)" fill="#125765"/>
<path id="Path_4722" data-name="Path 4722" d="M80.508,7.509h1.743a.958.958,0,0,0,.958-.957V.958A.958.958,0,0,0,82.251,0H80.508a.958.958,0,0,0-.958.958V6.552A.958.958,0,0,0,80.508,7.509Z" transform="translate(-75.266)" fill="#125765"/>
<path id="Path_4723" data-name="Path 4723" d="M345.416,7.509h1.743a.957.957,0,0,0,.958-.957V.958A.958.958,0,0,0,347.159,0h-1.743a.958.958,0,0,0-.958.958V6.552A.958.958,0,0,0,345.416,7.509Z" transform="translate(-324.865)" fill="#125765"/>
<g id="check" transform="translate(18.555 19.405)">
<path id="Subtraction_62" data-name="Subtraction 62" d="M10.146,11.936H1.79A1.793,1.793,0,0,1,0,10.145V1.789A1.793,1.793,0,0,1,1.79,0h8.356a1.793,1.793,0,0,1,1.791,1.791v8.356A1.793,1.793,0,0,1,10.146,11.936ZM5.976,6.271a4.006,4.006,0,0,0-2.191.6A1.693,1.693,0,0,0,2.939,8.26a1.691,1.691,0,0,0,.842,1.386,3.954,3.954,0,0,0,2.188.6,3.966,3.966,0,0,0,2.19-.6A1.712,1.712,0,0,0,9,8.254a1.679,1.679,0,0,0-.842-1.382A3.965,3.965,0,0,0,5.976,6.271ZM5.969,1.634a2.045,2.045,0,0,0-.05,4.089h.124a2.045,2.045,0,0,0-.074-4.089Z" fill="#2bb8a6"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30.491" height="31.183" viewBox="0 0 30.491 31.183">
<g id="calendar_3_" data-name="calendar (3)" transform="translate(-5.411 -1)">
<g id="Group_7900" data-name="Group 7900" transform="translate(5.411 1)">
<path id="Path_4721" data-name="Path 4721" d="M33.188,54.156v3.772A3.081,3.081,0,0,1,30.1,61.006H28.153a3.1,3.1,0,0,1-3.106-3.079V54.142h-8.78v3.786a3.1,3.1,0,0,1-3.106,3.079H11.213a3.081,3.081,0,0,1-3.088-3.079V54.156a2.808,2.808,0,0,0-2.714,2.793V79.055a2.809,2.809,0,0,0,2.8,2.812h24.9a2.812,2.812,0,0,0,2.8-2.812V56.949A2.808,2.808,0,0,0,33.188,54.156Zm-.9,23.522a1.208,1.208,0,0,1-1.208,1.208H10.185a1.208,1.208,0,0,1-1.208-1.208V66.259a1.208,1.208,0,0,1,1.208-1.209h20.89a1.209,1.209,0,0,1,1.208,1.209V77.678Z" transform="translate(-5.411 -50.683)" fill="#125765"/>
<path id="Path_4722" data-name="Path 4722" d="M80.609,8.3h1.927a1.058,1.058,0,0,0,1.059-1.058V1.059A1.059,1.059,0,0,0,82.536,0H80.609A1.059,1.059,0,0,0,79.55,1.059V7.242A1.058,1.058,0,0,0,80.609,8.3Z" transform="translate(-74.814)" fill="#125765"/>
<path id="Path_4723" data-name="Path 4723" d="M345.517,8.3h1.927A1.058,1.058,0,0,0,348.5,7.242V1.059A1.059,1.059,0,0,0,347.444,0h-1.927a1.059,1.059,0,0,0-1.059,1.059V7.242A1.058,1.058,0,0,0,345.517,8.3Z" transform="translate(-322.8)" fill="#125765"/>
<path id="Path_14055" data-name="Path 14055" d="M2.106,64.654h0a.485.485,0,0,0,.377.891L9.264,63.29,8,65.361a.393.393,0,0,0,.516.554l1.33-.691a.391.391,0,0,0,.1-.077l3.94-4.116,4.863-2.537c1.842-.993,1.628-1.756,1.519-1.966a1.039,1.039,0,0,0-.695-.5,4.132,4.132,0,0,0-1.762.029,2.282,2.282,0,0,1-.541.038c-.521-.014-.874.021-2.627.932L5.054,62.01l-3.718-1.93a.485.485,0,0,0-.447,0l-.627.326a.485.485,0,0,0-.155.734l2.581,3.215Z" transform="translate(5.078 -39.404)" fill="#2bb8a6"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="26.202" height="31.654" viewBox="0 0 26.202 31.654">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_5" data-name="Rectangle 5" width="10.833" height="10.822" fill="#125765"/>
</clipPath>
</defs>
<g id="Group_8916" data-name="Group 8916" transform="translate(-490.924 -27.365)">
<g id="Group_8650" data-name="Group 8650" transform="translate(506.98 27.365)">
<path id="Path_13666" data-name="Path 13666" d="M200.937,0h-6.128A2.008,2.008,0,0,0,192.8,2.009V11.2a.477.477,0,0,0,.763.381l1.915-1.437h5.458a2.008,2.008,0,0,0,2.009-2.009V2.009A2.008,2.008,0,0,0,200.937,0ZM197.4,7.592H195.32a.477.477,0,1,1,0-.953H197.4a.477.477,0,1,1,0,.953Zm3.03-2.043H195.32a.477.477,0,1,1,0-.953h5.106a.477.477,0,1,1,0,.953Zm0-2.043H195.32a.477.477,0,1,1,0-.953h5.106a.477.477,0,1,1,0,.953Zm0,0" transform="translate(-192.801 0)" fill="#2bb8a6"/>
</g>
<g id="Group_8915" data-name="Group 8915" transform="translate(490.924 36.213)">
<g id="Group_8651" data-name="Group 8651" transform="translate(2.608 0)">
<g id="Group_6" data-name="Group 6" transform="translate(0 0)">
<g id="Group_5" data-name="Group 5" clip-path="url(#clip-path)">
<path id="Path_9" data-name="Path 9" d="M10.8,0a5.412,5.412,0,0,0-.137,10.822.9.9,0,0,1,.251,0h.08A5.413,5.413,0,0,0,10.8,0" transform="translate(-5.38 0)" fill="#125765"/>
</g>
</g>
</g>
<path id="Path_13667" data-name="Path 13667" d="M13.821,26.891a11.321,11.321,0,0,0-11.574,0A4.5,4.5,0,0,0,0,30.574a4.462,4.462,0,0,0,2.235,3.661,10.537,10.537,0,0,0,5.793,1.608,10.537,10.537,0,0,0,5.793-1.608,4.5,4.5,0,0,0,2.235-3.684,4.491,4.491,0,0,0-2.235-3.66" transform="translate(0 -13.036)" fill="#125765"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="30.523" height="30.643" viewBox="0 0 30.523 30.643">
<g id="file_4_" data-name="file (4)" transform="translate(-1)">
<path id="Path_14061" data-name="Path 14061" d="M411,8.783v5.459h5.459Z" transform="translate(-385.462 -8.257)" fill="#125765"/>
<path id="Path_14062" data-name="Path 14062" d="M137.458,7.78a.9.9,0,0,1-.9-.9V0H123.693A2.7,2.7,0,0,0,121,2.693V12.729c.3-.027.6-.041.9-.041a9.859,9.859,0,0,1,7.612,3.591h9.744a.9.9,0,1,1,0,1.8h-8.561a9.8,9.8,0,0,1,1.039,3.591h7.522a.9.9,0,1,1,0,1.8h-7.522a9.879,9.879,0,0,1-4.163,7.182h14.079a2.7,2.7,0,0,0,2.693-2.693V7.78Zm1.8,4.908H126.087a.9.9,0,1,1,0-1.8h13.167a.9.9,0,1,1,0,1.8Z" transform="translate(-112.818)" fill="#125765"/>
<path id="Path_14063" data-name="Path 14063" d="M9.08,242a8.08,8.08,0,1,0,8.08,8.08A8.089,8.089,0,0,0,9.08,242Zm-.5,7.182h1a1.9,1.9,0,0,1,1.9,1.9v1a1.9,1.9,0,0,1-1.5,1.853v.342a.9.9,0,0,1-1.8,0v-.342a1.9,1.9,0,0,1-1.5-1.853.9.9,0,1,1,1.8,0,.1.1,0,0,0,.1.1h1a.1.1,0,0,0,.1-.1v-1a.1.1,0,0,0-.1-.1h-1a1.9,1.9,0,0,1-1.9-1.9v-1a1.9,1.9,0,0,1,1.5-1.853v-.342a.9.9,0,0,1,1.8,0v.342a1.9,1.9,0,0,1,1.5,1.853.9.9,0,0,1-1.8,0,.1.1,0,0,0-.1-.1h-1a.1.1,0,0,0-.1.1v1A.1.1,0,0,0,8.581,249.182Z" transform="translate(0 -227.517)" fill="#2bb8a6"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,15 @@
<svg id="Group_8652" data-name="Group 8652" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="22.284" height="31.654" viewBox="0 0 22.284 31.654">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_5" data-name="Rectangle 5" width="15.036" height="15.02" fill="#2bb8a6"/>
</clipPath>
</defs>
<g id="Group_8651" data-name="Group 8651" transform="translate(3.62 0)">
<g id="Group_6" data-name="Group 6" transform="translate(0 0)">
<g id="Group_5" data-name="Group 5" clip-path="url(#clip-path)">
<path id="Path_9" data-name="Path 9" d="M12.9,0a7.511,7.511,0,0,0-.19,15.02,1.249,1.249,0,0,1,.348,0h.111A7.512,7.512,0,0,0,12.9,0" transform="translate(-5.38 0)" fill="#2bb8a6"/>
</g>
</g>
</g>
<path id="Path_13667" data-name="Path 13667" d="M19.182,27.508c-4.416-2.944-11.617-2.944-16.064,0A6.247,6.247,0,0,0,0,32.62,6.194,6.194,0,0,0,3.1,37.7a14.624,14.624,0,0,0,8.04,2.232,14.624,14.624,0,0,0,8.04-2.232,6.246,6.246,0,0,0,3.1-5.112,6.233,6.233,0,0,0-3.1-5.08" transform="translate(0 -8.279)" fill="#125765"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32.774" height="32.788" viewBox="0 0 32.774 32.788">
<g id="park-tickets-couple" transform="translate(-0.205 0.001)">
<path id="Path_4724" data-name="Path 4724" d="M68.36,485.746a1.657,1.657,0,0,1-1.581,1.3.539.539,0,0,0-.206,1.025,1.656,1.656,0,0,1,.955,1.814l-.14.7a1.744,1.744,0,0,1-2.093,1.278c-.25-.06-.506-.106-.759-.156-.373-.073-.745-.15-1.118-.223-.493-.1-.985-.2-1.477-.3l-1.76-.353c-.655-.133-1.311-.263-1.967-.4-.7-.14-1.4-.279-2.1-.423-.719-.143-1.438-.289-2.153-.433l-2.133-.429-2.036-.409c-.622-.123-1.241-.25-1.863-.373-.539-.107-1.078-.216-1.614-.323l-1.291-.26-.888-.18c-.136-.027-.273-.057-.409-.083-.007,0-.013,0-.02,0a1.686,1.686,0,0,1-.12,1.062,1.705,1.705,0,0,1-1.87.958.5.5,0,0,0-.562.246l-.3.649a.5.5,0,0,0,.176.589c.033.027,24.018,11.084,24.058,11.094a.5.5,0,0,0,.562-.246l.3-.649a.5.5,0,0,0-.176-.589,1.7,1.7,0,0,1,1.388-3,.5.5,0,0,0,.562-.246l.3-.649a.5.5,0,0,0-.176-.589,1.7,1.7,0,0,1,1.388-3,.5.5,0,0,0,.562-.246l.3-.649a.5.5,0,0,0-.176-.589,1.7,1.7,0,0,1,1.388-3,.5.5,0,0,0,.562-.246l.329-.719a.41.41,0,0,0-.2-.546L68.416,485.5Z" transform="translate(-39.26 -469.349)" fill="#2bb8a6"/>
<path id="Path_4725" data-name="Path 4725" d="M.519,16.168c.04.02,25.932,5.214,25.975,5.214a.5.5,0,0,0,.489-.369l.14-.7a.5.5,0,0,0-.309-.532,1.7,1.7,0,0,1,.652-3.244.5.5,0,0,0,.489-.369l.1-.512.037-.19a.5.5,0,0,0-.309-.532,1.7,1.7,0,0,1,.652-3.244.5.5,0,0,0,.489-.369l.14-.7a.5.5,0,0,0-.309-.532,1.7,1.7,0,0,1,.652-3.244.5.5,0,0,0,.489-.369l.156-.775a.41.41,0,0,0-.323-.482S3.714,0,3.687,0a.412.412,0,0,0-.4.329L3.128,1.1a.5.5,0,0,0,.309.532A1.7,1.7,0,0,1,2.786,4.88.5.5,0,0,0,2.3,5.25l-.14.7a.5.5,0,0,0,.309.532,1.7,1.7,0,0,1-.652,3.244.5.5,0,0,0-.489.369l-.14.7a.5.5,0,0,0,.309.532A1.7,1.7,0,0,1,.842,14.57a.5.5,0,0,0-.489.369l-.14.7A.494.494,0,0,0,.519,16.168ZM22.7,7.639a.831.831,0,1,1,1.631.326l-1.1,5.464L22.555,16.8a.832.832,0,0,1-.815.669.9.9,0,0,1-.163-.017.833.833,0,0,1-.652-.978l.755-3.757ZM7.7,4.628a.831.831,0,0,1,1.631.326L8.948,6.84,8.519,8.98,8.173,10.7l-.616,3.081a.832.832,0,0,1-.815.669.9.9,0,0,1-.163-.017.4.4,0,0,1-.067-.017.829.829,0,0,1-.582-.962l.123-.622.323-1.611Z" fill="#125765"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" width="23.959" height="37.006" viewBox="0 0 23.959 37.006">
<g id="Layer_x0020_1" transform="translate(-300.998)">
<g id="_411123120" transform="translate(301)">
<g id="Group_8657" data-name="Group 8657" transform="translate(3.252)">
<path id="Path_13674" data-name="Path 13674" d="M612.691,6.612H619.8V1.691h-7.111ZM620.669,8.3h-8.823A.833.833,0,0,1,611,7.458V.845A.847.847,0,0,1,611.846,0h8.823a.861.861,0,0,1,.845.845V7.458A.847.847,0,0,1,620.669,8.3Z" transform="translate(-607.531)" fill="#2bb8a6"/>
<path id="Path_13675" data-name="Path 13675" d="M466.845,305h15.089a.833.833,0,0,1,.845.845,5.44,5.44,0,0,1-5.42,5.441h-5.918A5.478,5.478,0,0,1,466,305.845.847.847,0,0,1,466.845,305Z" transform="translate(-465.675 -298.388)" fill="#2bb8a6"/>
<path id="Path_13676" data-name="Path 13676" d="M527.845,0A.861.861,0,0,0,527,.845a.847.847,0,0,0,.846.845h12.444a.851.851,0,0,0,.867-.845A.865.865,0,0,0,540.289,0Z" transform="translate(-525.352)" fill="#2bb8a6"/>
<g id="Group_8656" data-name="Group 8656" transform="translate(0 33.863)">
<path id="Path_13677" data-name="Path 13677" d="M455.553,1562v.867a2.276,2.276,0,1,1-4.553,0V1562h4.553Z" transform="translate(-451 -1562)" fill="#2bb8a6"/>
<path id="Path_13678" data-name="Path 13678" d="M1050.553,1562v.867a2.276,2.276,0,0,1-4.553,0V1562h4.553Z" transform="translate(-1033.101 -1562)" fill="#2bb8a6"/>
</g>
</g>
<path id="Subtraction_59" data-name="Subtraction 59" d="M20570.063,22681.4h-16.975a.817.817,0,0,1-.238-.023,3.388,3.388,0,0,1-2.236-1.018,3.476,3.476,0,0,1-1.02-2.471v-19.4a3.557,3.557,0,0,1,1.02-2.475,3.457,3.457,0,0,1,1.906-.975,1.745,1.745,0,0,0-.193.8,6.288,6.288,0,0,0,6.289,6.285h5.92a6.288,6.288,0,0,0,6.285-6.285,1.692,1.692,0,0,0-.217-.8,3.472,3.472,0,0,1,2.949,3.449v19.4a3.476,3.476,0,0,1-1.02,2.471,3.383,3.383,0,0,1-2.236,1.018A.879.879,0,0,1,20570.063,22681.4Zm-10.756-7.187a2.114,2.114,0,1,0,1.494.619A2.1,2.1,0,0,0,20559.307,22674.211Zm4.027.732-.613.621.961.939-.961.943.613.621.963-.949v0l.973.949.609-.621-.961-.943.961-.939-.609-.621-.973.951Zm-4.025-6.031a2.112,2.112,0,0,0-.807,4.063,2.071,2.071,0,0,0,.809.164,2.113,2.113,0,0,0,0-4.227Zm3.543,1.406-.645.584,1.531,1.7,2.637-2.6-.609-.619-1.992,1.963Zm-3.539-6.709a2.158,2.158,0,0,0-.486.059,2.111,2.111,0,1,0,.969,4.109,2.123,2.123,0,0,0,1.57-2.545A2.1,2.1,0,0,0,20559.313,22663.609Zm3.539,1.266-.645.58,1.531,1.7,2.637-2.6-.609-.619-1.992,1.963Z" transform="translate(-20549.596 -22648.381)" fill="#125765"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" width="31.157" height="30.107" viewBox="0 0 31.157 30.107">
<g id="layer6" transform="translate(-0.52 -0.793)">
<g id="Group_7901" data-name="Group 7901" transform="translate(3.133 7.6)">
<path id="path856" d="M14.832,4.268,1.854,10.517V23.936A4.37,4.37,0,0,0,2.3,25.725a3.308,3.308,0,0,0,3.192,1.843H8.146l-.579-7.222a.519.519,0,0,1,.518-.564H8.23l.4-1.2a.518.518,0,0,1,.261-.3l2.588-1.293a4.468,4.468,0,0,1-.785-2.275l-1.218-.407a.517.517,0,0,1-.352-.49V10.441a4.877,4.877,0,0,1,.728-2.353c.731-1.17,2.247-2.317,4.981-2.317s4.25,1.148,4.982,2.317a4.877,4.877,0,0,1,.728,2.353v3.376a.519.519,0,0,1-.357.49l-1.213.407a4.466,4.466,0,0,1-.785,2.274l2.588,1.294a.518.518,0,0,1,.261.3l.4,1.2h.145a.519.519,0,0,1,.517.564l-.578,7.222h2.655a4.324,4.324,0,0,0,1.789-.44,3.332,3.332,0,0,0,1.847-3.192V10.517Z" transform="translate(-1.854 -4.268)" fill="#125765"/>
<path id="path854" d="M10.766,5.566c-2.457,0-3.537.925-4.1,1.831A3.753,3.753,0,0,0,6.1,9.2v3l.517.173v-1.1a.52.52,0,0,1,.4-.5A8.351,8.351,0,0,0,10.4,8.83a.52.52,0,0,1,.736,0,8.352,8.352,0,0,0,3.391,1.942.519.519,0,0,1,.394.5v1.1l.517-.173v-3a3.787,3.787,0,0,0-.571-1.8C14.3,6.49,13.223,5.566,10.766,5.566Z" transform="translate(2.211 -3.025)" fill="#125765"/>
<path id="path852" d="M8.536,11.172,5.892,12.5l-.223.666H16.682l-.223-.666-2.645-1.326a4.676,4.676,0,0,1-.542.418,5.619,5.619,0,0,1-2.023.793.52.52,0,0,1-.146,0A5.618,5.618,0,0,1,9.08,11.59,4.68,4.68,0,0,1,8.536,11.172Z" transform="translate(1.802 2.35)" fill="#125765"/>
<path id="path850" d="M5.323,12.719l.539,6.748h11.29l.538-6.748Zm6.184,1.56a1.558,1.558,0,1,1-1.555,1.555A1.562,1.562,0,0,1,11.507,14.279Z" transform="translate(1.471 3.833)" fill="#2bb8a6"/>
</g>
<path id="path831" d="M15.633.9,2,7.438A2.573,2.573,0,0,0,.618,9.029,2.689,2.689,0,0,0,2.141,12.2a2.58,2.58,0,0,0,2.112-.088L16.085,6.428,27.9,12.1a2.575,2.575,0,0,0,2.138.119,2.71,2.71,0,0,0,1.534-3.206A2.575,2.575,0,0,0,30.144,7.43L16.536.9A1.042,1.042,0,0,0,15.633.9Z" transform="translate(0)" fill="#125765"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22.334" height="22.334" viewBox="0 0 22.334 22.334">
<g id="answer" transform="translate(0.199 0.199)">
<g id="Group_7947" data-name="Group 7947">
<g id="Group_7946" data-name="Group 7946">
<path id="Path_4748" data-name="Path 4748" d="M19.194,0H2.742A2.745,2.745,0,0,0,0,2.742V15.081a2.745,2.745,0,0,0,2.742,2.742h7.54V21.25a.685.685,0,0,0,1.17.485l3.912-3.912h3.829a2.745,2.745,0,0,0,2.742-2.742V2.742A2.745,2.745,0,0,0,19.194,0Zm1.371,15.081a1.372,1.372,0,0,1-1.371,1.371H15.081a.682.682,0,0,0-.485.2L11.653,19.6V17.137a.685.685,0,0,0-.685-.685H2.742a1.372,1.372,0,0,1-1.371-1.371V2.742A1.372,1.372,0,0,1,2.742,1.371H19.194a1.372,1.372,0,0,1,1.371,1.371Z" fill="#fff" stroke="#fff" stroke-width="0.4"/>
</g>
</g>
<g id="Group_7949" data-name="Group 7949" transform="translate(6.232 4.114)">
<g id="Group_7948" data-name="Group 7948">
<path id="Path_4749" data-name="Path 4749" d="M150.83,96.43a.686.686,0,0,0-1.245,0l-4.113,8.911,1.245.574,1.4-3.031H152.3l1.4,3.031,1.245-.574Zm-2.081,5.084,1.459-3.161,1.459,3.161Z" transform="translate(-145.472 -96.032)" fill="#fff" stroke="#fff" stroke-width="0.4"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24.596" height="22.992" viewBox="0 0 24.596 22.992">
<g id="Group_7932" data-name="Group 7932" transform="translate(18780.988 21326)">
<path id="loading" d="M13.548,2.052a.8.8,0,0,0-.8-.8,11.5,11.5,0,1,0,11.5,11.5.8.8,0,0,0-1.6,0,9.892,9.892,0,1,1-9.892-9.892A.8.8,0,0,0,13.548,2.052Z" transform="translate(-18782.238 -21327.25)" fill="#fff" fill-rule="evenodd"/>
<path id="Path_4743" data-name="Path 4743" d="M130.861,64.468a.477.477,0,0,0-.675,0l-5.725,5.71L122.4,67.933a.477.477,0,0,0-.7.646l2.4,2.609a.477.477,0,0,0,.341.154h.01a.478.478,0,0,0,.337-.139l6.076-6.061A.477.477,0,0,0,130.861,64.468Z" transform="translate(-18895.777 -21378.832)" fill="#fff" stroke="#fff" stroke-width="0.7"/>
<g id="_06-Fast-forward" data-name="06-Fast-forward" transform="translate(-18769.16 -21328.994)">
<path id="Path_4750" data-name="Path 4750" d="M11.963,7.556l-4-3.326a.913.913,0,0,0-1.5.695V6.673L3.528,4.222a.913.913,0,0,0-1.478.7v7.045a.913.913,0,0,0,1.5.7L6.5,10.221v1.748a.913.913,0,0,0,1.5.7l4-3.326a1.157,1.157,0,0,0,0-1.782ZM3.055,12.1a.177.177,0,0,1-.285-.133V4.925a.174.174,0,0,1,.174-.174.177.177,0,0,1,.111.041L6.467,7.634V9.26ZM11.49,8.776l-4,3.326a.177.177,0,0,1-.285-.133V4.925a.174.174,0,0,1,.174-.174.177.177,0,0,1,.111.041l4,3.326a.418.418,0,0,1,0,.643Z" transform="translate(0 0)" fill="#fff" stroke="#fff" stroke-width="0.7"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22.992" height="22.992" viewBox="0 0 22.992 22.992">
<g id="Group_7924" data-name="Group 7924" transform="translate(18780.988 21326)">
<path id="loading" d="M13.548,2.052a.8.8,0,0,0-.8-.8,11.5,11.5,0,1,0,11.5,11.5.8.8,0,0,0-1.6,0,9.892,9.892,0,1,1-9.892-9.892A.8.8,0,0,0,13.548,2.052Z" transform="translate(-18782.238 -21327.25)" fill="#fff" fill-rule="evenodd"/>
<g id="Group_7923" data-name="Group 7923" transform="translate(-18775.25 -21323.49)">
<g id="Group_7923-2" data-name="Group 7923">
<path id="Path_4738" data-name="Path 4738" d="M137.993,64.575a.843.843,0,0,0-1.193,0L126.682,74.665,123.032,70.7a.843.843,0,1,0-1.241,1.143l4.245,4.61a.842.842,0,0,0,.6.272h.018a.844.844,0,0,0,.6-.246l10.74-10.712A.843.843,0,0,0,137.993,64.575Z" transform="translate(-121.568 -64.327)" fill="#fff"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 900 B

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.016" height="21.389" viewBox="0 0 25.016 21.389">
<g id="_06-Fast-forward" data-name="06-Fast-forward" transform="translate(-2.051 -4.018)">
<path id="Path_4750" data-name="Path 4750" d="M25.967,12.554,16.318,4.528A2.2,2.2,0,0,0,12.706,6.2v4.218L5.617,4.51A2.2,2.2,0,0,0,2.05,6.2v17A2.2,2.2,0,0,0,5.662,24.9L12.8,18.983V23.2A2.2,2.2,0,0,0,16.407,24.9l9.649-8.026a2.791,2.791,0,0,0,0-4.3ZM4.476,23.522a.428.428,0,0,1-.687-.321V6.2a.419.419,0,0,1,.419-.419.428.428,0,0,1,.268.1l8.231,6.858v3.924ZM24.825,15.5l-9.649,8.026a.428.428,0,0,1-.687-.321V6.2a.419.419,0,0,1,.419-.419.428.428,0,0,1,.268.1l9.649,8.026a1.008,1.008,0,0,1,0,1.552Z" transform="translate(0 0)" fill="#fff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 746 B

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22.992" height="22.992" viewBox="0 0 22.992 22.992">
<g id="Group_7925" data-name="Group 7925" transform="translate(18780.988 21326)">
<path id="loading" d="M13.548,2.052a.8.8,0,0,0-.8-.8,11.5,11.5,0,1,0,11.5,11.5.8.8,0,0,0-1.6,0,9.892,9.892,0,1,1-9.892-9.892A.8.8,0,0,0,13.548,2.052Z" transform="translate(-18782.238 -21327.25)" fill="#fff" fill-rule="evenodd"/>
<g id="add_6_" data-name="add (6)" transform="translate(-18769.49 -21351.07) rotate(45)">
<g id="Group_7929" data-name="Group 7929" transform="translate(25.172 20.286)">
<g id="Group_7928" data-name="Group 7928">
<path id="Path_4740" data-name="Path 4740" d="M238.576,134.1a.862.862,0,0,0-.862.862v9.772a.862.862,0,1,0,1.725,0v-9.772A.862.862,0,0,0,238.576,134.1Z" transform="translate(-237.714 -134.095)" fill="#fff"/>
</g>
</g>
<g id="Group_7931" data-name="Group 7931" transform="translate(20.286 25.172)">
<g id="Group_7930" data-name="Group 7930">
<path id="Path_4741" data-name="Path 4741" d="M144.73,237.714h-9.772a.862.862,0,0,0,0,1.725h9.772a.862.862,0,1,0,0-1.725Z" transform="translate(-134.095 -237.714)" fill="#fff"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="21.707" height="22.063" viewBox="0 0 21.707 22.063">
<path id="XMLID_352_" d="M25.593,12.443a.638.638,0,1,0-1.275,0v8.043H22.1V12.443a.638.638,0,1,0-1.275,0v8.043H18.6v-6.11a.638.638,0,0,0-1.275,0v6.11H15.1V18.037a.638.638,0,1,0-1.275,0v2.449H11.6V12.443a.638.638,0,1,0-1.275,0v8.043H8.1V12.443a.638.638,0,0,0-1.275,0v8.043H5.463V11.392h5.144a.638.638,0,0,0,.562-.336L13.71,6.314v9.8a.638.638,0,0,0,1.177.339l3.5-5.567h6.548a.638.638,0,0,0,0-1.275h-6.9a.638.638,0,0,0-.54.3L14.985,13.9V3.775a.638.638,0,0,0-1.2-.3l-3.56,6.642H5.463V.638a.638.638,0,0,0-1.275,0V21.124a.638.638,0,0,0,.638.638H24.934a.638.638,0,0,0,.638-.638s0,0,0-.007a.636.636,0,0,0,.022-.163Z" transform="translate(-4.037 0.15)" fill="#fff" stroke="#fff" stroke-width="0.3"/>
</svg>

After

Width:  |  Height:  |  Size: 799 B

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="21.598" height="21.598" viewBox="0 0 21.598 21.598">
<g id="Group_7939" data-name="Group 7939" transform="translate(18774.284 21319.584)">
<g id="return_1_" data-name="return (1)" transform="translate(-18774.285 -21319.584)">
<g id="Group_7940" data-name="Group 7940">
<path id="Path_4744" data-name="Path 4744" d="M12.6,0H.9a.9.9,0,0,0,0,1.8H12.6a7.2,7.2,0,0,1,0,14.4H3.072l2.063-2.063a.9.9,0,0,0-1.273-1.273l-3.6,3.6c-.021.021-.041.043-.06.066s-.016.021-.024.032-.02.025-.028.039-.016.026-.024.039-.015.024-.021.036-.013.027-.02.041-.013.026-.018.039-.01.027-.015.04-.011.028-.015.043-.007.027-.011.041-.008.029-.011.045-.005.032-.007.048,0,.026-.006.039a.906.906,0,0,0,0,.178c0,.013,0,.026.006.039s0,.032.007.048.007.03.011.045.006.027.011.041.01.029.015.043.009.027.015.04.012.026.018.039.013.027.02.041.014.024.021.036.015.026.024.039.019.026.028.039.015.022.024.032.038.045.059.065h0l3.6,3.6a.9.9,0,0,0,1.273-1.273L3.072,18H12.6a9,9,0,1,0,0-18Z" fill="#fff"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.568" height="20.088" viewBox="0 0 25.568 20.088">
<g id="Group_7941" data-name="Group 7941" transform="translate(18782.275 21324.551)">
<g id="transfer_4_" data-name="transfer (4)" transform="translate(-18782.275 -21375.75)">
<g id="Group_7945" data-name="Group 7945" transform="translate(0 51.198)">
<path id="Path_4747" data-name="Path 4747" d="M25.3,57.858l-6.392-6.392a.913.913,0,0,0-1.559.646v2.739H10.957a.913.913,0,0,0,0,1.826h7.305a.913.913,0,0,0,.913-.913V54.316L23.364,58.5l-4.188,4.188V61.243a.913.913,0,0,0-.913-.913H8.218V57.59a.913.913,0,0,0-1.559-.646L.267,63.337a.913.913,0,0,0,0,1.291L6.659,71.02a.913.913,0,0,0,.646.268.9.9,0,0,0,.35-.069.913.913,0,0,0,.563-.844V67.635H14.61a.913.913,0,0,0,0-1.826H7.3a.913.913,0,0,0-.913.913V68.17L2.2,63.982l4.188-4.188v1.448a.913.913,0,0,0,.913.913H17.35V64.9a.913.913,0,0,0,1.559.646L25.3,59.149A.913.913,0,0,0,25.3,57.858Z" transform="translate(0 -51.198)" fill="#fff"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22.992" height="21.078" viewBox="0 0 22.992 21.078">
<g id="Group_7944" data-name="Group 7944" transform="translate(18776.197 21320.653)">
<g id="repeat_1_" data-name="repeat (1)" transform="translate(-18776.197 -21320.652)">
<g id="Group_7943" data-name="Group 7943" transform="translate(0 0)">
<g id="Group_7942" data-name="Group 7942" transform="translate(0 0)">
<path id="Path_4745" data-name="Path 4745" d="M157.956,24.2h-5.362l1.239-1.239a.958.958,0,1,0-1.355-1.355L149.6,24.477c-.022.022-.043.046-.063.07s-.017.023-.026.034-.021.027-.03.041-.017.028-.025.042-.016.025-.023.039-.014.029-.021.043-.013.027-.019.042-.011.029-.016.043-.011.03-.016.046-.008.029-.011.043-.008.031-.012.048-.005.034-.008.05,0,.028-.006.042c0,.031,0,.062,0,.094h0q0,.047,0,.094c0,.014,0,.028.006.042s0,.034.008.05.008.032.012.048.007.029.011.043.011.031.016.046.01.029.016.043.013.028.019.042.013.029.021.043.015.026.023.039.016.028.025.042.02.028.03.041.016.023.025.034.041.048.063.07l2.874,2.874a.958.958,0,1,0,1.355-1.355l-1.239-1.239h5.351a5.744,5.744,0,0,1,5.749,5.749,5.2,5.2,0,0,1-1.532,3.684.958.958,0,1,0,1.356,1.354,7.114,7.114,0,0,0,2.093-5.038A7.66,7.66,0,0,0,157.956,24.2Z" transform="translate(-142.617 -21.322)" fill="#fff"/>
<path id="Path_4746" data-name="Path 4746" d="M16.1,150.139c.01-.014.021-.027.03-.041s.017-.028.025-.042.016-.025.023-.039.014-.029.021-.044.013-.027.019-.041.011-.029.016-.043.011-.03.016-.046.008-.029.011-.044.008-.031.012-.047.005-.034.008-.051,0-.028.006-.042a.964.964,0,0,0,0-.189c0-.014,0-.028-.006-.042s0-.034-.008-.051-.008-.032-.012-.047-.007-.029-.011-.043-.011-.03-.016-.046-.01-.029-.016-.043-.013-.028-.019-.041-.013-.029-.021-.044-.015-.026-.023-.039-.016-.028-.025-.042-.02-.027-.03-.041-.017-.023-.026-.034-.041-.047-.063-.069h0l-2.874-2.874a.958.958,0,1,0-1.355,1.355l1.239,1.239H7.665a5.744,5.744,0,0,1-5.749-5.749,5.2,5.2,0,0,1,1.532-3.684.958.958,0,0,0-1.356-1.354A7.114,7.114,0,0,0,0,142.859a7.66,7.66,0,0,0,7.654,7.665h5.362l-1.239,1.239a.958.958,0,0,0,1.355,1.355l2.874-2.874h0q.033-.033.063-.07C16.079,150.162,16.087,150.151,16.1,150.139Z" transform="translate(0 -132.32)" fill="#fff"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

@ -0,0 +1,103 @@
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
class ChatApiClient {
static final ChatApiClient _instance = ChatApiClient._internal();
ChatApiClient._internal();
factory ChatApiClient() => _instance;
Future<user.UserAutoLoginModel> getUserLoginToken() async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin",
{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
},
);
user.UserAutoLoginModel userLoginResponse = user.userAutoLoginModelFromJson(
response.body,
);
return userLoginResponse;
}
Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSearchMember}$sName/$cUserId",
token: AppState().chatDetails!.response!.token,
);
return searchUserJsonModel(response.body);
}
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(
json.decode(str).map((x) => ChatUser.fromJson(x)),
);
Future<ChatUserModel> getRecentChats() async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}",
token: AppState().chatDetails!.response!.token,
);
return ChatUserModel.fromJson(
json.decode(response.body),
);
}
Future<ChatUserModel> getFavUsers() async {
Response favRes = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
return ChatUserModel.fromJson(
json.decode(favRes.body),
);
}
Future<Response> getSingleUserChatHistory({required int senderUID, required int receiverUID, required bool loadMore, bool isNewChat = false, required int paginationVal}) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal",
token: AppState().chatDetails!.response!.token,
);
return response;
}
Future<fav.FavoriteChatUser> favUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser",
{
"targetUserId": targetUserID,
"userId": userID,
},
token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
}
Future<fav.FavoriteChatUser> unFavUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser",
{"targetUserId": targetUserID, "userId": userID},
token: AppState().chatDetails!.response!.token,
);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
return favoriteChatUser;
}
Future<StreamedResponse> uploadMedia(String userId, File file) async {
dynamic request = MultipartRequest('POST', Uri.parse('${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}'));
request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll({'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}'});
StreamedResponse response = await request.send();
return response;
}
}

@ -186,4 +186,18 @@ class DashboardApiClient {
);
return chatUnreadCovnCountModelFromJson(response.body);
}
// Future setAdvertisementViewed(String masterID, int advertisementId) async {
// String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed";
//
// Map<String, dynamic> postParams = {
// "ItgNotificationMasterId": masterID,
// "ItgAdvertisement": {"advertisementId": advertisementId, "acknowledgment": true} //Mobile Id
// };
// postParams.addAll(AppState().postParamsJson);
// return await ApiClient().postJsonForObject((json) {
// // ItgMainRes responseData = ItgMainRes.fromJson(json);
// return json;
// }, url, postParams);
// }
}

@ -22,8 +22,8 @@ class MyAttendanceApiClient {
String url = "${ApiConsts.erpRest}GET_EIT_TRANSACTIONS";
Map<String, dynamic> postParams = {"P_PAGE_LIMIT": 50, "P_PAGE_NUM": 1, "P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E", "P_FUNCTION_NAME": pFunctionName};
postParams.addAll(AppState().postParamsJson);
// postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty){
// postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
// AppState().postParamsJson['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
print(empID);
@ -38,7 +38,7 @@ class MyAttendanceApiClient {
String url = "${ApiConsts.erpRest}GET_EIT_DFF_STRUCTURE";
Map<String, dynamic> postParams = {"P_SELECTED_RESP_ID": -999, "P_MENU_TYPE": "E", "P_FUNCTION_NAME": pFunctionName};
postParams.addAll(AppState().postParamsJson);
if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) {
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
@ -47,21 +47,21 @@ class MyAttendanceApiClient {
}, url, postParams);
}
Future<List<ESERVICESVS>> getValueSetValues(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List<Map<String, dynamic>> list,{ String? empID, String? parentValue}) async {
Future<List<ESERVICESVS>> getValueSetValues(String pSegmentName, String pDescFlexContextCode, String pDescFlexName, List<Map<String, dynamic>> list, {String? empID, String? parentValue}) async {
String url = "${ApiConsts.erpRest}GET_VALUE_SET_VALUES";
Map<String, dynamic> postParams = {
"P_SELECTED_RESP_ID": -999,
"P_MENU_TYPE": "E",
"P_PAGE_LIMIT": 1000,
"P_PAGE_NUM": 1,
"P_PARENT_VALUE": empID!.isNotEmpty? parentValue : null,
"P_PARENT_VALUE": empID!.isNotEmpty ? parentValue : null,
"P_SEGMENT_NAME": pSegmentName,
"P_DESC_FLEX_CONTEXT_CODE": pDescFlexContextCode,
"P_DESC_FLEX_NAME": pDescFlexName,
"GetValueSetValuesTBL": list,
};
postParams.addAll(AppState().postParamsJson);
if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) {
if (empID.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
@ -82,7 +82,7 @@ class MyAttendanceApiClient {
"GetValueSetValuesTBL": list,
};
postParams.addAll(AppState().postParamsJson);
if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) {
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
@ -91,7 +91,7 @@ class MyAttendanceApiClient {
}, url, postParams);
}
Future<GenericResponseModel?> validateEitTransaction(String pDescFlexContextCode, String pFunctionName, List<Map<String, dynamic>> list, { String? empID}) async {
Future<GenericResponseModel?> validateEitTransaction(String pDescFlexContextCode, String pFunctionName, List<Map<String, dynamic>> list, {String? empID}) async {
String url = "${ApiConsts.erpRest}VALIDATE_EIT_TRANSACTION";
Map<String, dynamic> postParams = {
"P_SELECTED_RESP_ID": -999,
@ -101,7 +101,7 @@ class MyAttendanceApiClient {
"EITTransactionTBL": list,
};
postParams.addAll(AppState().postParamsJson);
if('P_SELECTED_EMPLOYEE_NUMBER'.isNotEmpty) {
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
@ -110,7 +110,7 @@ class MyAttendanceApiClient {
}, url, postParams);
}
Future<SubmitEITTransactionList> submitEitTransaction(String pDescFlexContextCode, String pFunctionName, List<Map<String, dynamic>> list) async {
Future<SubmitEITTransactionList> submitEitTransaction(String pDescFlexContextCode, String pFunctionName, List<Map<String, dynamic>> list, {String? empID}) async {
String url = "${ApiConsts.erpRest}SUBMIT_EIT_TRANSACTION";
Map<String, dynamic> postParams = {
"P_SELECTED_RESP_ID": -999,
@ -121,6 +121,9 @@ class MyAttendanceApiClient {
"EITTransactionTBLModel": list,
};
postParams.addAll(AppState().postParamsJson);
if (empID!.isNotEmpty) {
postParams['P_SELECTED_EMPLOYEE_NUMBER'] = empID;
}
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
return responseData.submitEITTransactionList!; //ESERVICESDV.fromJson(responseData.getDefaultValueList!.toJson());
@ -129,12 +132,7 @@ class MyAttendanceApiClient {
Future<ResubmitEITRequestResponse> reSubmitEitTransaction(String itemKey, var notifID, List<Map<String, dynamic>> list) async {
String url = "${ApiConsts.erpRest}RESUBMIT_EIT_TRANSACTION";
Map<String, dynamic> postParams = {
"P_NOTIFICATION_ID": notifID,
"P_ITEM_KEY": itemKey,
"P_EMAIL_ADDRESS": AppState().memberInformationList!.eMPLOYEEEMAILADDRESS,
"EITTransactionTBL": list
};
Map<String, dynamic> postParams = {"P_NOTIFICATION_ID": notifID, "P_ITEM_KEY": itemKey, "P_EMAIL_ADDRESS": AppState().memberInformationList!.eMPLOYEEEMAILADDRESS, "EITTransactionTBL": list};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);

@ -17,6 +17,7 @@ class MyColors {
static const Color greyF7Color = Color(0xffF7F7F7);
static const Color grey80Color = Color(0xff808080);
static const Color grey70Color = Color(0xff707070);
static const Color grey7BColor = Color(0xff7B7B7B);
static const Color greyACColor = Color(0xffACACAC);
static const Color grey98Color = Color(0xff989898);
static const Color lightGreyEFColor = Color(0xffEFEFEF);

@ -1,6 +1,6 @@
class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server
//static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
@ -10,10 +10,12 @@ class ApiConsts {
static String user = baseUrlServices + "api/User/";
static String cocRest = baseUrlServices + "COCWS.svc/REST/";
// todo @aamir move api end point last repo to concerned method.
//Chat
static String chatServerBaseUrl = "https://apiderichat.hmg.com";
static String chatServerBaseApiUrl = "https://apiderichat.hmg.com/api/";
static String chatHubConnectionUrl = chatServerBaseUrl + "/ConnectionChatHub";
static String chatServerBaseUrl = "https://apiderichat.hmg.com/";
static String chatServerBaseApiUrl = chatServerBaseUrl + "api/";
static String chatHubConnectionUrl = chatServerBaseUrl + "ConnectionChatHub";
static String chatSearchMember = "user/getUserWithStatusAndFavAsync/";
static String chatRecentUrl = "UserChatHistory/getchathistorybyuserid"; //For a Mem
static String chatSingleUserHistoryUrl = "UserChatHistory/GetUserChatHistory";

@ -44,7 +44,7 @@ extension WidgetExtensions on Widget {
child: this,
);
Widget objectContainerView({String title = "", String note = "", bool disablePadding = false, double radius = 15}) {
Widget objectContainerView({String title = "", String note = "", bool disablePadding = false, double radius = 15, bool center = true}) {
return Container(
padding: disablePadding ? EdgeInsets.zero : const EdgeInsets.only(top: 15, bottom: 15, left: 14, right: 14),
decoration: BoxDecoration(
@ -58,7 +58,7 @@ extension WidgetExtensions on Widget {
),
],
),
alignment: Alignment.center,
alignment: center == true ? Alignment.center : null,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,

@ -3,7 +3,7 @@ import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/codegen_loader.g.dart';

@ -7,7 +7,7 @@ import 'dart:convert';
class CallDataModel {
CallDataModel({
this.callerId,
this.callReciverId,
this.callReceiverID,
this.notificationForeground,
this.message,
this.title,
@ -27,7 +27,7 @@ class CallDataModel {
});
String? callerId;
String? callReciverId;
String? callReceiverID;
String? notificationForeground;
String? message;
String? title;
@ -51,7 +51,7 @@ class CallDataModel {
factory CallDataModel.fromJson(Map<String, dynamic> json) => CallDataModel(
callerId: json["callerID"] == null ? null : json["callerID"],
callReciverId: json["callReciverID"] == null ? null : json["callReciverID"],
callReceiverID: json["callReceiverID"] == null ? null : json["callReceiverID"],
notificationForeground: json["notification_foreground"] == null ? null : json["notification_foreground"],
message: json["message"] == null ? null : json["message"],
title: json["title"] == null ? null : json["title"],
@ -78,7 +78,7 @@ class CallDataModel {
Map<String, dynamic> toJson() => {
"callerID": callerId == null ? null : callerId,
"callReciverID": callReciverId == null ? null : callReciverId,
"callReceiverID": callReceiverID == null ? null : callReceiverID,
"notification_foreground": notificationForeground == null ? null : notificationForeground,
"message": message == null ? null : message,
"title": title == null ? null : title,

@ -19,21 +19,21 @@ class ChatUserModel {
}
class ChatUser {
ChatUser({
this.id,
this.userName,
this.email,
this.phone,
this.title,
this.userStatus,
this.image,
this.unreadMessageCount,
this.userAction,
this.isPin,
this.isFav,
this.isAdmin,
this.isTyping,
});
ChatUser(
{this.id,
this.userName,
this.email,
this.phone,
this.title,
this.userStatus,
this.image,
this.unreadMessageCount,
this.userAction,
this.isPin,
this.isFav,
this.isAdmin,
this.isTyping,
this.isLoadingCounter});
int? id;
String? userName;
@ -48,6 +48,7 @@ class ChatUser {
bool? isFav;
bool? isAdmin;
bool? isTyping;
bool? isLoadingCounter;
factory ChatUser.fromJson(Map<String, dynamic> json) => ChatUser(
id: json["id"] == null ? null : json["id"],
@ -63,6 +64,7 @@ class ChatUser {
isFav: json["isFav"] == null ? null : json["isFav"],
isAdmin: json["isAdmin"] == null ? null : json["isAdmin"],
isTyping: false,
isLoadingCounter: true,
);
Map<String, dynamic> toJson() => {

@ -1,21 +1,21 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:logger/logger.dart' as L;
import 'package:logging/logging.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/get_search_user_chat_model.dart';
import 'package:mohem_flutter_app/models/chat/get_single_user_chat_list_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as login;
import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/image_picker.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:uuid/uuid.dart';
@ -26,9 +26,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
TextEditingController search = TextEditingController();
List<SingleUserChatModel> userChatHistory = [];
List<ChatUser>? pChatHistory, searchedChats;
late HubConnection hubConnection;
L.Logger logger = L.Logger();
bool hubConInitialized = false;
String chatCID = '';
bool isLoading = true;
bool isChatScreenActive = false;
@ -40,56 +37,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
List<ChatUser> favUsersList = [];
int paginationVal = 0;
Future<void> getUserAutoLoginToken(BuildContext cxt) async {
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}user/externaluserlogin",
{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
},
);
login.UserAutoLoginModel userLoginResponse = login.userAutoLoginModelFromJson(
response.body,
);
if (userLoginResponse.response != null) {
hubConInitialized = true;
AppState().setchatUserDetails = userLoginResponse;
await buildHubConnection();
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
return;
}
}
Future<List<ChatUser>?> getChatMemberFromSearch(String sName, int cUserId) async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSearchMember}$sName/$cUserId",
token: AppState().chatDetails!.response!.token,
);
return searchUserJsonModel(response.body);
void registerEvents() {
hubConnection.on("OnUpdateUserStatusAsync", changeStatus);
hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping);
hubConnection.on("OnUserCountAsync", userCountAsync);
hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
}
List<ChatUser> searchUserJsonModel(String str) => List<ChatUser>.from(
json.decode(str).map(
(x) => ChatUser.fromJson(x),
),
);
void getUserRecentChats() async {
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatRecentUrl}",
token: AppState().chatDetails!.response!.token,
);
ChatUserModel recentChat = userToList(response.body);
Response favRes = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatFavoriteUsers}${AppState().chatDetails!.response!.id}",
token: AppState().chatDetails!.response!.token,
);
ChatUserModel favUList = userToList(favRes.body);
ChatUserModel recentChat = await ChatApiClient().getRecentChats();
ChatUserModel favUList = await ChatApiClient().getFavUsers();
if (favUList.response != null && recentChat.response != null) {
favUsersList = favUList.response!;
@ -108,21 +69,20 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
pChatHistory = recentChat.response ?? [];
pChatHistory!.sort(
(ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(
b.userName!.toLowerCase(),
),
(ChatUser a, ChatUser b) => a.userName!.toLowerCase().compareTo(b.userName!.toLowerCase()),
);
searchedChats = pChatHistory;
isLoading = false;
await invokeUserChatHistoryNotDeliveredAsync(
userId: int.parse(
AppState().chatDetails!.response!.id.toString(),
),
);
notifyListeners();
}
Future getUserChatHistoryNotDeliveredAsync({required int userId}) async {
await hubConnection.invoke(
"GetUserChatHistoryNotDeliveredAsync",
args: [userId],
);
Future invokeUserChatHistoryNotDeliveredAsync({required int userId}) async {
await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
return "";
}
@ -131,9 +91,11 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
if (isNewChat) userChatHistory = [];
if (!loadMore) paginationVal = 0;
isChatScreenActive = true;
Response response = await ApiClient().getJsonForResponse(
"${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatSingleUserHistoryUrl}/$senderUID/$receiverUID/$paginationVal",
token: AppState().chatDetails!.response!.token,
Response response = await ChatApiClient().getSingleUserChatHistory(
senderUID: senderUID,
receiverUID: receiverUID,
loadMore: loadMore,
paginationVal: paginationVal,
);
if (response.statusCode == 204) {
if (isNewChat) {
@ -156,9 +118,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
).reversed.toList();
}
}
await getUserChatHistoryNotDeliveredAsync(
userId: senderUID,
);
isLoading = false;
notifyListeners();
markRead(
@ -173,24 +132,28 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatCID = uuid.v4();
}
void markRead(List<SingleUserChatModel> data, reciverID) {
for (SingleUserChatModel element in data!) {
if (!element.isSeen!) {
dynamic data = [
{
"userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.targetUserId,
"isDelivered": true,
"isSeen": true,
void markRead(List<SingleUserChatModel> data, int receiverID) {
if (data != null) {
for (SingleUserChatModel element in data!) {
if (element.isSeen != null) {
if (!element.isSeen!) {
dynamic data = [
{
"userChatHistoryId": element.userChatHistoryId,
"TargetUserId": element.targetUserId,
"isDelivered": true,
"isSeen": true,
}
];
updateUserChatHistoryStatusAsync(data);
}
];
updateUserChatHistoryStatusAsync(data);
}
}
}
for (ChatUser element in searchedChats!) {
if (element.id == reciverID) {
element.unreadMessageCount = 0;
notifyListeners();
for (ChatUser element in searchedChats!) {
if (element.id == receiverID) {
element.unreadMessageCount = 0;
notifyListeners();
}
}
}
}
@ -208,27 +171,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
),
);
ChatUserModel userToList(String str) => ChatUserModel.fromJson(
json.decode(str),
);
Future<dynamic> uploadAttachments(String userId, File file) async {
dynamic result;
dynamic request = MultipartRequest(
'POST',
Uri.parse(
'${ApiConsts.chatServerBaseApiUrl}${ApiConsts.chatMediaImageUploadUrl}',
),
);
request.fields.addAll({'userId': userId, 'fileSource': '1'});
request.files.add(await MultipartFile.fromPath('files', file.path));
request.headers.addAll(
{
'Authorization': 'Bearer ${AppState().chatDetails!.response!.token}',
},
);
try {
StreamedResponse response = await request.send();
StreamedResponse response = await ChatApiClient().uploadMedia(userId, file);
if (response.statusCode == 200) {
result = jsonDecode(
await response.stream.bytesToString(),
@ -237,59 +183,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
result = [];
}
} catch (e) {
if (kDebugMode) {
print(e);
}
print(e);
}
;
return result;
}
Future<void> buildHubConnection() async {
HttpConnectionOptions httpOp = HttpConnectionOptions(
skipNegotiation: false,
logMessageContent: true,
);
hubConnection = HubConnectionBuilder()
.withUrl(
ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}",
options: httpOp,
)
.withAutomaticReconnect(
retryDelays: <int>[2000, 5000, 10000, 20000],
)
.configureLogging(
Logger("Loggin"),
)
.build();
hubConnection.onclose(
({Exception? error}) {},
);
hubConnection.onreconnecting(
({Exception? error}) {},
);
hubConnection.onreconnected(
({String? connectionId}) {},
);
if (hubConnection.state != HubConnectionState.Connected) {
await hubConnection.start();
getUserChatHistoryNotDeliveredAsync(
userId: int.parse(
AppState().chatDetails!.response!.id.toString(),
),
);
hubConnection.on("OnUpdateUserStatusAsync", changeStatus);
hubConnection.on("OnDeliveredChatUserAsync", onMsgReceived);
// hubConnection.on("OnSeenChatUserAsync", onChatSeen);
//hubConnection.on("OnUserTypingAsync", onUserTyping);
hubConnection.on("OnUserCountAsync", userCountAsync);
hubConnection.on("OnUpdateUserChatHistoryWindowsAsync", updateChatHistoryWindow);
hubConnection.on("OnGetUserChatHistoryNotDeliveredAsync", chatNotDelivered);
hubConnection.on("OnUpdateUserChatHistoryStatusAsync", updateUserChatStatus);
}
}
void updateUserChatStatus(List<Object?>? args) {
dynamic items = args!.toList();
for (dynamic cItem in items[0]) {
@ -342,32 +241,23 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
void chatNotDelivered(List<Object?>? args) {
dynamic items = args!.toList();
logger.d(items);
for (dynamic item in items[0]) {
searchedChats!.forEach((element) {
if (element.id == item["currentUserId"]) {
var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount;
element.unreadMessageCount = val! + 1;
}
});
// dynamic data = [
// {
// "userChatHistoryId": item["userChatHistoryId"],
// "TargetUserId": item["targetUserId"],
// "isDelivered": true,
// "isSeen": true,
// }
// ];
// updateUserChatHistoryStatusAsync(data);
searchedChats!.forEach(
(ChatUser element) {
if (element.id == item["currentUserId"]) {
int? val = element.unreadMessageCount ?? 0;
element.unreadMessageCount = val! + 1;
}
element.isLoadingCounter = false;
},
);
}
notifyListeners();
}
void changeStatus(List<Object?>? args) {
if (kDebugMode) {
// print("================= Status Online // Offline ====================");
}
dynamic items = args!.toList();
// logger.d(items);
for (ChatUser user in searchedChats!) {
if (user.id == items.first["id"]) {
user.userStatus = items.first["userStatus"];
@ -402,14 +292,8 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
data.first.currentUserId = temp.first.targetUserId;
data.first.currentUserName = temp.first.targetUserName;
}
logger.d(jsonEncode(data));
userChatHistory.insert(0, data.first);
// searchedChats!.forEach((element) {
// if (element.id == data.first.currentUserId) {
// var val = element.unreadMessageCount == null ? 0 : element.unreadMessageCount;
// element.unreadMessageCount = val! + 1;
// }
// });
var list = [
{
"userChatHistoryId": data.first.userChatHistoryId,
@ -419,14 +303,10 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
];
updateUserChatHistoryStatusAsync(list);
notifyListeners();
// if (isChatScreenActive) scrollToBottom();
}
void onUserTyping(List<Object?>? parameters) {
// print("==================== Typing Active ==================");
// logger.d(parameters);
for (ChatUser user in searchedChats!) {
if (user.id == parameters![1] && parameters[0] == true) {
user.isTyping = parameters[0] as bool?;
@ -561,7 +441,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
if (!isFileSelected && !isMsgReply) {
logger.d("Normal Text Message");
if (message.text == null || message.text.isEmpty) {
return;
}
@ -569,14 +448,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
if (isFileSelected && !isMsgReply) {
Utils.showLoading(context);
//logger.d("Normal Attachment Message");
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path);
Utils.hideLoading(context);
sendChatToServer(chatEventId: 2, fileTypeId: getFileType(ext.toString()), targetUserId: targetUserId, targetUserName: targetUserName, isAttachment: true, chatReplyId: null, isReply: false);
}
if (!isFileSelected && isMsgReply) {
// logger.d("Normal Text Message With Reply");
if (message.text == null || message.text.isEmpty) {
return;
}
@ -584,7 +461,6 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
chatEventId: 1, fileTypeId: null, targetUserId: targetUserId, targetUserName: targetUserName, chatReplyId: repliedMsg.first.userChatHistoryId, isAttachment: false, isReply: true);
}
if (isFileSelected && isMsgReply) {
// logger.d("Attachment Message With Reply");
Utils.showLoading(context);
dynamic value = await uploadAttachments(AppState().chatDetails!.response!.id.toString(), selectedFile);
String? ext = getFileExtension(selectedFile.path);
@ -697,9 +573,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
Future<void> favoriteUser({required int userID, required int targetUserID}) async {
Response response =
await ApiClient().postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/addFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().favUser(userID: userID, targetUserID: targetUserID);
if (favoriteChatUser.response != null) {
for (ChatUser user in searchedChats!) {
if (user.id == favoriteChatUser.response!.targetUserId!) {
@ -712,16 +586,16 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
Future<void> unFavoriteUser({required int userID, required int targetUserID}) async {
Response response = await ApiClient()
.postJsonForResponse("${ApiConsts.chatServerBaseApiUrl}FavUser/deleteFavUser", {"targetUserId": targetUserID, "userId": userID}, token: AppState().chatDetails!.response!.token);
fav.FavoriteChatUser favoriteChatUser = fav.FavoriteChatUser.fromRawJson(response.body);
fav.FavoriteChatUser favoriteChatUser = await ChatApiClient().unFavUser(userID: userID, targetUserID: targetUserID);
if (favoriteChatUser.response != null) {
for (var user in searchedChats!) {
for (ChatUser user in searchedChats!) {
if (user.id == favoriteChatUser.response!.targetUserId!) {
user.isFav = favoriteChatUser.response!.isFav;
}
}
favUsersList.removeWhere((ChatUser element) => element.id == targetUserID);
favUsersList.removeWhere(
(ChatUser element) => element.id == targetUserID,
);
}
notifyListeners();
}
@ -773,4 +647,12 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
curve: Curves.easeIn,
);
}
// void getUserChatHistoryNotDeliveredAsync({required int userId}) async {
// try {
// await hubConnection.invoke("GetUserChatHistoryNotDeliveredAsync", args: [userId]);
// } finally {
// hubConnection.off("GetUserChatHistoryNotDeliveredAsync", method: chatNotDelivered);
// }
// }
}

@ -1,13 +1,17 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/api/offers_and_discounts_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/chat_count_conversation_model.dart';
import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart';
import 'package:mohem_flutter_app/models/dashboard/drawer_menu_item_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_accrual_balances_list_model.dart';
import 'package:mohem_flutter_app/models/dashboard/get_attendance_tracking_list_model.dart';
@ -21,6 +25,7 @@ import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/itg/itg_response_model.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:signalr_netcore/signalr_client.dart';
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
// ignore: prefer_mixin
@ -37,6 +42,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
//Chat
bool isChatCounterLoding = true;
bool isChatHubLoding = true;
int chatUConvCounter = 0;
//Misssing Swipe
@ -97,6 +103,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
leaveBalanceAccrual = null;
isChatCounterLoding = true;
isChatHubLoding = true;
chatUConvCounter = 0;
ticketBalance = 0;
@ -287,6 +294,28 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
}
}
Future<void> getUserAutoLoginToken() async {
logger.d("Token Generated On Home");
UserAutoLoginModel userLoginResponse = await ChatApiClient().getUserLoginToken();
if (userLoginResponse.response != null) {
AppState().setchatUserDetails = userLoginResponse;
} else {
Utils.showToast(
userLoginResponse.errorResponses!.first.fieldName.toString() + " Erorr",
);
}
}
Future<HubConnection> getHubConnection() async {
HubConnection hub;
HttpConnectionOptions httpOp = HttpConnectionOptions(skipNegotiation: false, logMessageContent: true);
hub = HubConnectionBuilder()
.withUrl(ApiConsts.chatHubConnectionUrl + "?UserId=${AppState().chatDetails!.response!.id}&source=Web&access_token=${AppState().chatDetails!.response!.token}", options: httpOp)
.withAutomaticReconnect(retryDelays: <int>[2000, 5000, 10000, 20000]).build();
isChatHubLoding = false;
return hub;
}
void notify() {
notifyListeners();
}

@ -91,6 +91,8 @@ class _IncomingCallState extends State<IncomingCall> with SingleTickerProviderSt
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: const <Widget>[
// todo @aamir, need to use extension mehtods
Text(
"Aamir Saleem Ahmad",
style: TextStyle(

@ -3,7 +3,8 @@ import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:sizer/sizer.dart';
// todo: @aamir use extension methods, and use correct widgets.
class ChatBubble extends StatelessWidget {
const ChatBubble(
@ -28,6 +29,8 @@ class ChatBubble extends StatelessWidget {
@override
Widget build(BuildContext context) {
return isCurrentUser ? currentUser(context) : receiptUser(context);
return Padding(
// padding: EdgeInsets.zero,
padding: EdgeInsets.only(
@ -132,12 +135,12 @@ class ChatBubble extends StatelessWidget {
color: isCurrentUser ? MyColors.grey41Color.withOpacity(.5) : MyColors.white.withOpacity(0.7),
),
if (isCurrentUser) 5.width,
// if (isCurrentUser)
// Icon(
// isDelivered ? Icons.done_all : Icons.done_all,
// color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
// size: 14,
// ),
if (isCurrentUser)
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
),
],
),
],
@ -147,4 +150,58 @@ class ChatBubble extends StatelessWidget {
),
);
}
Widget currentUser(context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(text).toText12(),
Align(
alignment: Alignment.centerRight,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
dateTime.toText10(color: MyColors.grey41Color.withOpacity(.5)),
7.width,
Icon(
isDelivered ? Icons.done_all : Icons.done_all,
color: isSeen ? MyColors.textMixColor : MyColors.grey9DColor,
size: 14,
),
],
),
),
],
).paddingOnly(top: 11, left: 13, right: 7, bottom: 5).objectContainerView(disablePadding: true).paddingOnly(left: MediaQuery.of(context).size.width * 0.3);
}
Widget receiptUser(context) {
return Container(
padding: const EdgeInsets.only(top: 11, left: 13, right: 7, bottom: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: const LinearGradient(
transform: GradientRotation(.83),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
MyColors.gradiantEndColor,
MyColors.gradiantStartColor,
],
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(text).toText12(color: Colors.white),
Align(
alignment: Alignment.centerRight,
child: dateTime.toText10(
color: Colors.white.withOpacity(.71),
),
),
],
),
).paddingOnly(right: MediaQuery.of(context).size.width * 0.3);
}
}

@ -1,20 +1,19 @@
import 'dart:async';
import 'dart:convert';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/chat/call.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/call/chat_outgoing_call_screen.dart';
import 'package:mohem_flutter_app/ui/chat/chat_bubble.dart';
import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
import 'package:provider/provider.dart';
@ -38,18 +37,17 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
void getMoreChat() async {
if (userDetails != null) {
data.paginationVal = data.paginationVal + 10;
if (userDetails != null)
if (userDetails != null) {
data.getSingleUserChatHistory(
senderUID: AppState().chatDetails!.response!.id!.toInt(),
receiverUID: userDetails["targetUser"].id,
loadMore: true,
isNewChat: false,
);
}
}
await Future.delayed(
const Duration(
milliseconds: 1000,
),
const Duration(milliseconds: 1000),
);
_rc.loadComplete();
}
@ -68,284 +66,173 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
}
return Scaffold(
backgroundColor: const Color(0xFFF8F8F8),
appBar: AppBarWidget(context,
title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false,
image: userDetails["targetUser"].image,
actions: [
IconButton(
onPressed: () {
// makeCall(
// callType: "AUDIO",
// con: data.hubConnection,
// );
},
icon: SvgPicture.asset(
"assets/icons/chat/call.svg",
width: 22,
height: 22,
),
),
IconButton(
onPressed: () {
// makeCall(
// callType: "VIDEO",
// con: data.hubConnection,
// );
},
icon: SvgPicture.asset(
"assets/icons/chat/video_call.svg",
width: 20,
height: 20,
),
),
10.width,
]),
backgroundColor: MyColors.backgroundColor,
appBar: AppBarWidget(
context,
title: userDetails["targetUser"].userName.toString().replaceAll(".", " ").capitalizeFirstofEach,
showHomeButton: false,
image: userDetails["targetUser"].image,
actions: [
IconButton(
onPressed: () {
makeCall(callType: "AUDIO", con: hubConnection);
},
icon: SvgPicture.asset("assets/icons/chat/call.svg", width: 22, height: 22),
),
IconButton(
onPressed: () {
makeCall(callType: "VIDEO", con: hubConnection);
},
icon: SvgPicture.asset("assets/icons/chat/video_call.svg", width: 20, height: 20),
),
10.width,
],
),
body: Consumer<ChatProviderModel>(
builder: (BuildContext context, ChatProviderModel m, Widget? child) {
return (m.isLoading
? ChatHomeShimmer()
: Column(
children: <Widget>[
Expanded(
flex: 2,
child: SmartRefresher(
enablePullDown: false,
enablePullUp: true,
onLoading: () {
getMoreChat();
},
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _rc,
SmartRefresher(
enablePullDown: false,
enablePullUp: true,
onLoading: () {
getMoreChat();
},
header: const MaterialClassicHeader(
color: MyColors.gradiantEndColor,
),
controller: _rc,
reverse: true,
child: ListView.separated(
controller: m.scrollController,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
reverse: true,
child: ListView.builder(
controller: m.scrollController,
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
reverse: true,
itemCount: m.userChatHistory.length,
padding: const EdgeInsets.only(top: 20),
itemBuilder: (BuildContext context, int i) {
return SwipeTo(
iconColor: MyColors.lightGreenColor,
child: ChatBubble(
text: m.userChatHistory[i].contant.toString(),
replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "",
isSeen: m.userChatHistory[i].isSeen == true ? true : false,
isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false,
isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false,
dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false,
userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(),
),
onRightSwipe: () {
m.chatReply(
m.userChatHistory[i],
);
},
);
},
),
itemCount: m.userChatHistory.length,
padding: const EdgeInsets.all(21),
separatorBuilder: (cxt, index) => 8.height,
itemBuilder: (BuildContext context, int i) {
return SwipeTo(
iconColor: MyColors.lightGreenColor,
child: ChatBubble(
text: m.userChatHistory[i].contant.toString(),
replyText: m.userChatHistory[i].userChatReplyResponse != null ? m.userChatHistory[i].userChatReplyResponse!.contant.toString() : "",
isSeen: m.userChatHistory[i].isSeen == true ? true : false,
isCurrentUser: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id ? true : false,
isDelivered: m.userChatHistory[i].currentUserId == AppState().chatDetails!.response!.id && m.userChatHistory[i].isDelivered == true ? true : false,
dateTime: m.dateFormte(m.userChatHistory[i].createdDate!),
isReplied: m.userChatHistory[i].userChatReplyResponse != null ? true : false,
userName: AppState().chatDetails!.response!.userName == m.userChatHistory[i].currentUserName.toString() ? "You" : m.userChatHistory[i].currentUserName.toString(),
),
onRightSwipe: () {
m.chatReply(
m.userChatHistory[i],
);
},
);
},
),
),
).expanded,
if (m.isMsgReply)
Row(
children: <Widget>[
Container(
height: 80,
color: MyColors.textMixColor,
width: 6,
),
Expanded(
child: Container(
height: 80,
color: MyColors.black.withOpacity(0.10),
child: ListTile(
title: (AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString()
? "You"
: m.repliedMsg.first.currentUserName.toString().replaceAll(".", " "))
.toText14(color: MyColors.lightGreenColor),
subtitle: (m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(
color: MyColors.white,
maxLine: 2,
),
trailing: GestureDetector(
onTap: m.closeMe,
child: Container(
decoration: BoxDecoration(
color: MyColors.white.withOpacity(0.5),
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: const Icon(
Icons.close,
size: 23,
color: MyColors.white,
),
),
),
SizedBox(
height: 82,
child: Row(
children: <Widget>[
Container(height: 82, color: MyColors.textMixColor, width: 6),
Container(
color: MyColors.darkTextColor.withOpacity(0.10),
padding: const EdgeInsets.only(top: 11, left: 14, bottom: 14, right: 21),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(AppState().chatDetails!.response!.userName == m.repliedMsg.first.currentUserName.toString()
? "You"
: m.repliedMsg.first.currentUserName.toString().replaceAll(".", " "))
.toText14(color: MyColors.lightGreenColor),
(m.repliedMsg.isNotEmpty ? m.repliedMsg.first.contant! : "").toText12(color: MyColors.grey71Color, maxLine: 2)
],
).expanded,
12.width,
const Icon(Icons.cancel, size: 23, color: MyColors.grey7BColor).onPress(m.closeMe),
],
),
),
),
],
).expanded,
],
),
),
if (m.isFileSelected && m.sFileType == ".png" || m.sFileType == ".jpeg" || m.sFileType == ".jpg")
Card(
margin: EdgeInsets.zero,
elevation: 0,
child: Padding(
padding: const EdgeInsets.only(
left: 20,
right: 20,
top: 20,
bottom: 0,
),
child: Card(
margin: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
elevation: 0,
child: Container(
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: FileImage(
m.selectedFile,
SizedBox(height: 200, width: double.infinity, child: Image.file(m.selectedFile, fit: BoxFit.cover)).paddingOnly(left: 21, right: 21, top: 21),
TextField(
controller: m.message,
decoration: InputDecoration(
hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color, fontSize: 14),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(left: m.sFileType.isNotEmpty ? 10 : 20, right: m.sFileType.isNotEmpty ? 0 : 5, top: 20, bottom: 20),
prefixIconConstraints: BoxConstraints(),
prefixIcon: m.sFileType.isNotEmpty ? SvgPicture.asset(m.getType(m.sFileType), height: 30, width: 22, alignment: Alignment.center, fit: BoxFit.cover) : null,
suffixIcon: SizedBox(
width: 96,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center, // added line
children: <Widget>[
if (m.sFileType.isNotEmpty)
IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.centerRight,
icon: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
decoration: const BoxDecoration(
color: MyColors.redA3Color,
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
child: const Icon(Icons.close, size: 15, color: MyColors.white),
),
("Clear").toText11(color: MyColors.redA3Color).paddingOnly(left: 4),
],
),
fit: BoxFit.cover,
),
borderRadius: const BorderRadius.all(
Radius.circular(0),
onPressed: () async {
m.removeAttachment();
},
),
),
child: const SizedBox(
width: double.infinity,
height: 200,
),
),
),
),
),
Card(
margin: EdgeInsets.zero,
child: TextField(
controller: m.message,
decoration: InputDecoration(
hintText: m.isFileSelected ? m.selectedFile.path.split("/").last : LocaleKeys.typeheretoreply.tr(),
hintStyle: TextStyle(
color: m.isFileSelected ? MyColors.darkTextColor : MyColors.grey98Color,
fontSize: 14,
),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
contentPadding: EdgeInsets.only(
left: m.sFileType.isNotEmpty ? 10 : 20,
right: m.sFileType.isNotEmpty ? 0 : 5,
top: 20,
bottom: 20,
),
prefixIcon: m.sFileType.isNotEmpty
? Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SvgPicture.asset(
m.getType(m.sFileType),
height: 30,
width: 25,
alignment: Alignment.center,
fit: BoxFit.cover,
).paddingOnly(left: 20),
],
)
: null,
suffixIcon: SizedBox(
width: 96,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center, // added line
children: <Widget>[
if (m.sFileType.isNotEmpty)
IconButton(
if (m.sFileType.isEmpty)
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.centerRight,
icon: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
decoration: const BoxDecoration(
color: MyColors.redA3Color,
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
child: const Icon(
Icons.close,
size: 15,
color: MyColors.white,
),
),
("Clear")
.toText11(
color: MyColors.redA3Color,
)
.paddingOnly(
left: 4,
),
],
),
alignment: Alignment.topRight,
icon: const Icon(Icons.attach_file_rounded, size: 26, color: MyColors.grey3AColor),
onPressed: () async {
m.removeAttachment();
m.selectImageToUpload(context);
},
),
if (m.sFileType.isEmpty)
RotationTransition(
turns: const AlwaysStoppedAnimation(45 / 360),
child: IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.topRight,
icon: const Icon(
Icons.attach_file_rounded,
size: 26,
color: MyColors.grey3AColor,
),
onPressed: () async {
m.selectImageToUpload(context);
},
),
),
IconButton(
alignment: Alignment.centerRight,
padding: EdgeInsets.zero,
icon: SvgPicture.asset(
"assets/icons/chat/chat_send_icon.svg",
height: 26,
width: 26,
),
onPressed: () {
m.sendChatMessage(
userDetails["targetUser"].id,
userDetails["targetUser"].userName,
context,
);
},
)
],
),
).paddingOnly(
right: 20,
),
IconButton(
alignment: Alignment.centerRight,
padding: EdgeInsets.zero,
icon: SvgPicture.asset("assets/icons/chat/chat_send_icon.svg", height: 26, width: 26),
onPressed: () {
m.sendChatMessage(userDetails["targetUser"].id, userDetails["targetUser"].userName, context);
},
)
],
),
),
).paddingOnly(right: 20),
),
),
],
@ -357,38 +244,41 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
void makeCall({required String callType, required HubConnection con}) async {
print("================== Make call Triggered ============================");
logger.d(jsonEncode(AppState().chatDetails!.response));
Map<String, dynamic> json = {
"callerID": AppState().chatDetails!.response!.id!.toString(),
"callReciverID": userDetails["targetUser"].id.toString(),
"callReceiverID": userDetails["targetUser"].id.toString(),
"notification_foreground": "true",
"message": "Aamir is calling ",
"message": "Aamir is calling",
"title": "Video Call",
"type": callType == "VIDEO" ? "Video" : "Audio",
"identity": "Aamir.Muhammad",
"name": "Aamir Saleem Ahmad",
"identity": AppState().chatDetails!.response!.userName,
"name": AppState().chatDetails!.response!.title,
"is_call": "true",
"is_webrtc": "true",
"contant": "Start video Call Aamir.Muhammad",
"contant": "Start video Call ${AppState().chatDetails!.response!.userName}",
"contantNo": "775d1f11-62d9-6fcc-91f6-21f8c14559fb",
"chatEventId": "3",
"fileTypeId": null,
"currentUserId": "266642",
"currentUserId": AppState().chatDetails!.response!.id!.toString(),
"chatSource": "1",
"userChatHistoryLineRequestList": [
{"isSeen": false, "isDelivered": false, "targetUserId": 341682, "targetUserStatus": 4}
{
"isSeen": false,
"isDelivered": false,
"targetUserId": userDetails["targetUser"].id,
"targetUserStatus": 4,
}
],
// "server": "https://192.168.8.163:8086",
"server": "https://livecareturn.hmg.com:8086",
};
CallDataModel incomingCallData = CallDataModel.fromJson(json);
CallDataModel callData = CallDataModel.fromJson(json);
await Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => OutGoingCall(
isVideoCall: callType == "VIDEO" ? true : false,
OutGoingCallData: incomingCallData,
OutGoingCallData: callData,
),
),
);

@ -1,19 +1,13 @@
import 'dart:convert';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/ui/chat/chat_home_screen.dart';
import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart';
import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/items_for_sale.dart';
import 'package:mohem_flutter_app/ui/screens/items_for_sale/fragments/my_posted_ads_fragment.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';
@ -31,32 +25,21 @@ class _ChatHomeState extends State<ChatHome> {
@override
void initState() {
// TODO: implement initState
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.getUserAutoLoginToken(context).whenComplete(() {
data.getUserRecentChats();
});
}
@override
void dispose() {
super.dispose();
data.clearAll();
if (data.hubConInitialized) {
data.hubConnection.stop();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColors.white,
appBar: AppBarWidget(
context,
title: LocaleKeys.chat.tr(),
showHomeButton: true,
),
appBar: AppBarWidget(context, title: LocaleKeys.chat.tr(), showHomeButton: true),
body: Column(
children: <Widget>[
Container(

@ -2,13 +2,13 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheets/search_employee_bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart';
@ -21,6 +21,16 @@ class ChatHomeScreen extends StatefulWidget {
class _ChatHomeScreenState extends State<ChatHomeScreen> {
TextEditingController search = TextEditingController();
late ChatProviderModel data;
@override
void initState() {
// TODO: implement initState
super.initState();
data = Provider.of<ChatProviderModel>(context, listen: false);
data.registerEvents();
data.getUserRecentChats();
}
@override
void dispose() {
@ -41,50 +51,30 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
physics: const AlwaysScrollableScrollPhysics(),
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
vertical: 20,
horizontal: 20,
),
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
child: TextField(
controller: m.search,
style: const TextStyle(color: MyColors.darkTextColor, fontWeight: FontWeight.w500, fontSize: 12),
onChanged: (String val) {
m.filter(val);
},
decoration: InputDecoration(
border: fieldBorder(
radius: 5,
color: 0xFFE5E5E5,
),
focusedBorder: fieldBorder(
radius: 5,
color: 0xFFE5E5E5,
),
enabledBorder: fieldBorder(
radius: 5,
color: 0xFFE5E5E5,
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
border: fieldBorder(radius: 5, color: 0xFFE5E5E5),
focusedBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5),
enabledBorder: fieldBorder(radius: 5, color: 0xFFE5E5E5),
contentPadding: const EdgeInsets.all(11),
hintText: LocaleKeys.searchfromchat.tr(),
hintStyle: const TextStyle(
color: MyColors.lightTextColor,
fontStyle: FontStyle.italic,
),
hintStyle: const TextStyle(color: MyColors.lightTextColor, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500, fontSize: 12),
filled: true,
fillColor: const Color(
0xFFF7F7F7,
),
fillColor: const Color(0xFFF7F7F7),
suffixIconConstraints: const BoxConstraints(),
suffixIcon: m.search.text.isNotEmpty
? IconButton(
constraints: const BoxConstraints(),
onPressed: () {
m.clearSelections();
},
icon: const Icon(
Icons.clear,
size: 22,
),
icon: const Icon(Icons.clear, size: 22),
color: MyColors.redA3Color,
)
: null,
@ -94,14 +84,13 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
if (m.searchedChats != null)
ListView.separated(
itemCount: m.searchedChats!.length,
padding: const EdgeInsets.only(
bottom: 80,
),
padding: const EdgeInsets.only(bottom: 80),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 55,
// todo @aamir, remove list tile, make a custom ui instead
child: ListTile(
leading: Stack(
children: <Widget>[
@ -135,6 +124,22 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
mainAxisAlignment: MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
// if (m.searchedChats![index].isLoadingCounter!)
// Flexible(
// child: Container(
// padding: EdgeInsets.zero,
// alignment: Alignment.centerRight,
// width: 18,
// height: 18,
// decoration: const BoxDecoration(
// // color: MyColors.redColor,
// borderRadius: BorderRadius.all(
// Radius.circular(20),
// ),
// ),
// child: CircularProgressIndicator(),
// ),
// ),
if (m.searchedChats![index].unreadMessageCount! > 0)
Flexible(
child: Container(
@ -193,7 +198,7 @@ class _ChatHomeScreenState extends State<ChatHomeScreen> {
AppRoutes.chatDetailed,
arguments: {"targetUser": m.searchedChats![index], "isNewChat": false},
).then((Object? value) {
// m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString()));
// m.GetUserChatHistoryNotDeliveredAsync(userId: int.parse(AppState().chatDetails!.response!.id.toString()));
m.clearSelections();
m.notifyListeners();
});

@ -1,7 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/provider/chat_provider_model.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/utils.dart';

@ -1,12 +1,15 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/flutter_countdown_timer.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -16,6 +19,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart';
import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/landing/itg/its_add_screen_video_image.dart';
import 'package:mohem_flutter_app/ui/landing/widget/app_drawer.dart';
import 'package:mohem_flutter_app/ui/landing/widget/menus_widget.dart';
import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart';
@ -26,6 +30,9 @@ import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'
import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart';
import 'package:provider/provider.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:signalr_netcore/signalr_client.dart';
late HubConnection hubConnection;
class DashboardScreen extends StatefulWidget {
DashboardScreen({Key? key}) : super(key: key);
@ -49,13 +56,26 @@ class _DashboardScreenState extends State<DashboardScreen> {
super.initState();
scheduleMicrotask(() {
data = Provider.of<DashboardProviderModel>(context, listen: false);
_bHubCon();
_onRefresh();
});
}
void buildHubConnection() async {
hubConnection = await data.getHubConnection();
await hubConnection.start();
}
@override
void dispose() {
super.dispose();
hubConnection.stop();
}
void _bHubCon() {
data.getUserAutoLoginToken().whenComplete(() {
buildHubConnection();
});
}
void _onRefresh() async {
@ -84,26 +104,21 @@ class _DashboardScreenState extends State<DashboardScreen> {
// actions: [
// IconButton(
// onPressed: () {
// data.getITGNotification().then((value) {
// print("--------------------detail_1-----------------");
// if (value!.result!.data != null) {
// print(value.result!.data!.notificationMasterId);
// print(value.result!.data!.notificationType);
// if (value.result!.data!.notificationType == "Survey") {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: value.result!.data);
// data.getITGNotification().then((val) {
// if (val!.result!.data != null) {
// if (val.result!.data!.notificationType == "Survey") {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);
// } else {
// DashboardApiClient().getAdvertisementDetail(value.result!.data!.notificationMasterId ?? "").then(
// DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
// (value) {
// if (value!.mohemmItgResponseItem!.statusCode == 200) {
// if (value.mohemmItgResponseItem!.result!.data != null) {
// String? image64 = value.mohemmItgResponseItem!.result!.data!.advertisement!.viewAttachFileColl!.first.base64String;
// print(image64);
// var sp = image64!.split("base64,");
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => MovieTheaterBody(
// encodedBytes: sp[1],
// builder: (BuildContext context) => ITGAdsScreen(
// addMasterId: val.result!.data!.notificationMasterId!,
// advertisement: value.mohemmItgResponseItem!.result!.data!.advertisement!,
// ),
// ),
// );

@ -0,0 +1,136 @@
import 'dart:convert';
import 'dart:io' as Io;
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/itg/advertisement.dart' as ads;
import 'package:path_provider/path_provider.dart';
import 'package:video_player/video_player.dart';
class ITGAdsScreen extends StatefulWidget {
final String addMasterId;
final ads.Advertisement advertisement;
const ITGAdsScreen({required this.addMasterId, required this.advertisement});
@override
_ITGAdsScreenState createState() => _ITGAdsScreenState();
}
class _ITGAdsScreenState extends State<ITGAdsScreen> {
late Future<VideoPlayerController> _futureController;
late VideoPlayerController _controller;
bool skip = false;
bool isVideo = false;
bool isImage = false;
String ext = '';
late File imageFile;
void checkFileType() async {
String? rFile = widget.advertisement!.viewAttachFileColl!.first.base64String;
String? rFileExt = widget.advertisement!.viewAttachFileColl!.first.fileName;
ext = "." + rFileExt!.split(".").last.toLowerCase();
if (ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".gif") {
await processImage(rFile!);
isImage = true;
} else {
isVideo = true;
_futureController = createVideoPlayer(rFile!);
}
setState(() {});
}
Future processImage(String encodedBytes) async {
try {
Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last);
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1
imageFile = Io.File("${appDocumentsDirectory.path}/addImage$ext");
imageFile.writeAsBytesSync(decodedBytes);
} catch (e) {
logger.d(e);
}
}
Future<VideoPlayerController> createVideoPlayer(String encodedBytes) async {
try {
Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last);
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1
File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4");
file.writeAsBytesSync(decodedBytes);
VideoPlayerController controller = VideoPlayerController.file(file);
await controller.initialize();
await controller.play();
await controller.setVolume(1.0);
await controller.setLooping(false);
return controller;
} catch (e) {
return new VideoPlayerController.asset("dataSource");
}
}
@override
void initState() {
checkFileType();
initTimer();
super.initState();
}
void initTimer() {
Future.delayed(const Duration(seconds: 5), () {
setState(() {
skip = true;
});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height * .25;
return Scaffold(
body: Column(
children: [
if (isVideo)
SizedBox(
height: MediaQuery.of(context).size.height * .3,
child: FutureBuilder(
future: _futureController,
builder: (BuildContext context, AsyncSnapshot<Object?> snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) {
_controller = snapshot.data as VideoPlayerController;
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
),
if (isImage) Image.file(imageFile),
if (skip)
ElevatedButton(
onPressed: () async {
// DashboardApiClient().setAdvertisementViewed(widget.addMasterId, widget.advertisement!.advertisementId!).then((value) {
// logger.d(value);
// });
},
child: const Text("Go To Dashboard"),
)
],
),
);
}
}

@ -1,96 +0,0 @@
import 'dart:convert';
import 'dart:io' as Io;
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class MovieTheaterBody extends StatefulWidget {
final String encodedBytes;
const MovieTheaterBody({required this.encodedBytes});
@override
_MovieTheaterBodyState createState() => _MovieTheaterBodyState();
}
class _MovieTheaterBodyState extends State<MovieTheaterBody> {
late Future<VideoPlayerController> _futureController;
late VideoPlayerController _controller;
Future<VideoPlayerController> createVideoPlayer() async {
try {
var decodedBytes = base64Decode(widget.encodedBytes);
var file = Io.File("decodedBezkoder.mp4");
file.writeAsBytesSync(decodedBytes);
VideoPlayerController controller = VideoPlayerController.file(file);
await controller.initialize();
await controller.setLooping(true);
return controller;
} catch (e) {
print("object0000000");
print(e);
return new VideoPlayerController.asset("dataSource");
}
}
@override
void initState() {
_futureController = createVideoPlayer();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Expanded(
child: FutureBuilder(
future: _futureController,
builder: (context, snapshot) {
//UST: 05/2021 - MovieTheaterBody - id:11 - 2pts - Criação
if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) {
_controller = snapshot.data as VideoPlayerController;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
),
const SizedBox(
height: 50,
),
FloatingActionButton(
onPressed: () {
setState(() {
if (_controller.value.isPlaying) {
_controller.pause();
} else {
// If the video is paused, play it.
_controller.play();
}
});
},
backgroundColor: Colors.green[700],
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
)
],
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
),
);
}
}

@ -92,8 +92,9 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_EXTRA_INFO_ID", nUMBERVALUE: -1, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson());
values.add(ValidateEitTransactionModel(dATEVALUE: null, nAME: "PEI_OBJECT_VERSION_NUMBER", nUMBERVALUE: 0, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: null).toJson());
genericResponseModel = await MyAttendanceApiClient().validateEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID:dynamicParams!.selectedEmp ??'');
SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values);
genericResponseModel = await MyAttendanceApiClient().validateEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp ?? '');
SubmitEITTransactionList submitEITTransactionList =
await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp ?? '');
Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit'));
@ -112,23 +113,27 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
Future calGetValueSetValues(GetEITDFFStructureList structureList) async {
try {
Utils.showLoading(context);
String segmentId = structureList.cHILDSEGMENTSVS!;
if (dESCFLEXCONTEXTCODE.isEmpty) dESCFLEXCONTEXTCODE = structureList.dESCFLEXCONTEXTCODE!;
List<GetEITDFFStructureList> filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? [];
List<Map<String, dynamic>> values = filteredList
.map((e) => GetSetValuesRequestModel(
sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME)
.toJson())
.toList();
List<ESERVICESVS> eServicesResponseModel = await MyAttendanceApiClient().getValueSetValues(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!,
values, empID:dynamicParams!.selectedEmp ??'', parentValue: structureList.eSERVICESDV!.pVALUECOLUMNNAME );
List<GetEITDFFStructureList> abc = genericResponseModel?.getEITDFFStructureList ?? [];
getEitDffStructureList = abc;
int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == structureList.cHILDSEGMENTSVS);
getEitDffStructureList![index].eSERVICESVS!.clear();
if (eServicesResponseModel.isNotEmpty) getEitDffStructureList![index].eSERVICESVS!.addAll(eServicesResponseModel);
// getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? [];
//getEitDffStructureList = getEitDffStructureList!.where((element) => element.dISPLAYFLAG != "N").toList();
for (int i = 0; i < (structureList.cHILDSEGMENTSVSSplited?.length ?? 0); i++) {
String segmentId = structureList.cHILDSEGMENTSVSSplited![i];
if (dESCFLEXCONTEXTCODE.isEmpty) dESCFLEXCONTEXTCODE = structureList.dESCFLEXCONTEXTCODE!;
List<GetEITDFFStructureList> filteredList = getEitDffStructureList?.where((element) => element.cHILDSEGMENTSVSSplited!.contains(segmentId)).toList() ?? [];
List<Map<String, dynamic>> values = filteredList
.map((e) => GetSetValuesRequestModel(
sEGMENTNAME: e.sEGMENTNAME, vALUECOLUMNNAME: e.eSERVICESDV!.pVALUECOLUMNNAME, dESCRIPTION: "", iDCOLUMNNAME: e.eSERVICESDV!.pIDCOLUMNNAME, fLEXVALUESETNAME: e.fLEXVALUESETNAME)
.toJson())
.toList();
List<ESERVICESVS> eServicesResponseModel = await MyAttendanceApiClient().getValueSetValues(segmentId, structureList.dESCFLEXCONTEXTCODE!, structureList.dESCFLEXNAME!, values,
empID: dynamicParams!.selectedEmp ?? '', parentValue: structureList.eSERVICESDV!.pVALUECOLUMNNAME);
List<GetEITDFFStructureList> abc = genericResponseModel?.getEITDFFStructureList ?? [];
getEitDffStructureList = abc;
int index = getEitDffStructureList!.indexWhere((element) => element.sEGMENTNAME == segmentId);
getEitDffStructureList![index].eSERVICESVS!.clear();
if (eServicesResponseModel.isNotEmpty) getEitDffStructureList![index].eSERVICESVS!.addAll(eServicesResponseModel);
// getEitDffStructureList = genericResponseModel?.getEITDFFStructureList ?? [];
//getEitDffStructureList = getEitDffStructureList!.where((element) => element.dISPLAYFLAG != "N").toList();
}
await Future.delayed(const Duration(seconds: 1));
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
@ -394,7 +399,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
Widget build(BuildContext context) {
if (dynamicParams == null) {
dynamicParams = ModalRoute.of(context)!.settings.arguments as DynamicListViewParams;
if(dynamicParams!.selectedEmp.isNotEmpty){
if (dynamicParams!.selectedEmp.isNotEmpty) {
AppState().postParamsJson['P_SELECTED_EMPLOYEE_NUMBER'] = dynamicParams!.selectedEmp;
}
getTransactionsStructure();

@ -39,7 +39,7 @@ class _TeamMembersState extends State<TeamMembers> {
try {
Utils.showLoading(context);
getEmployeeSubordinatesList = await MyTeamApiClient().getEmployeeSubordinates(searchEmpEmail.toString(), searchEmpName.toString(), searchEmpNo.toString());
// getEmployeeSubordinatesList = await MyTeamApiClient().employeeSubordinates(searchEmpEmail.toString(), searchEmpName.toString(), searchEmpNo.toString(),getEmployeeSubordinates?.eMPLOYEENUMBER);
getEmployeeSubordinatesList = await MyTeamApiClient().employeeSubordinates(searchEmpEmail.toString(), searchEmpName.toString(), searchEmpNo.toString(),getEmployeeSubordinates?.eMPLOYEENUMBER);
Utils.hideLoading(context);
setState(() {});
} catch (ex) {

@ -25,7 +25,8 @@ class PersonalInfo extends StatelessWidget {
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
// mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
LocaleKeys.category.tr().toText13(color: MyColors.lightGrayColor),
(memberInformationList.eMPLOYMENTCATEGORYMEANING ?? "").toText16(),
@ -42,7 +43,7 @@ class PersonalInfo extends StatelessWidget {
LocaleKeys.Payroll.tr().toText13(color: MyColors.lightGrayColor),
(memberInformationList.pAYROLLNAME ?? "").toText16(),
],
).objectContainerView().paddingAll(21),
).objectContainerView(center: false).paddingAll(21),
),
);
}

@ -1,11 +1,13 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/itg_forms_models/wf_history_model.dart';
import 'package:mohem_flutter_app/ui/work_list/sheets/delegate_sheet.dart';
import 'package:mohem_flutter_app/ui/work_list/sheets/selected_itg_item_sheet.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
@ -109,6 +111,19 @@ class ApprovalLevelfragment extends StatelessWidget {
}).expanded,
Container(width: 1, height: 30, color: MyColors.lightGreyEFColor),
LocaleKeys.delegate.tr().toText12(color: MyColors.gradiantEndColor).center.paddingOnly(top: 6, bottom: 6).onPress(() {
if (history.employeeID == AppState().memberInformationList?.eMPLOYEENUMBER) {
showMyBottomSheet(context,
callBackFunc: voidCallback,
child: DelegateSheet(
title: LocaleKeys.delegate.tr(),
apiMode: "Delegate",
notificationID: null,
actionHistoryList: null,
wFHistory: wFHistory,
callBackFunc: voidCallback,
));
return;
}
showMyBottomSheet(
context,
callBackFunc: voidCallback,
@ -135,11 +150,7 @@ class ApprovalLevelfragment extends StatelessWidget {
return MyColors.yellowColor;
} else if (code.toLowerCase() == "not doable" || code.toLowerCase() == "rejected") {
return MyColors.redColor;
} else if (code.toLowerCase() == "approved" ||
code.toLowerCase() == "auto-approve" ||
code.toLowerCase() == "auto-approved" ||
code.toLowerCase() == "doable" ||
code.toLowerCase() == "answer") {
} else if (code.toLowerCase() == "approved" || code.toLowerCase() == "auto-approve" || code.toLowerCase() == "auto-approved" || code.toLowerCase() == "doable" || code.toLowerCase() == "answer") {
return MyColors.greenColor;
} else if (code.toLowerCase() == "requested information" || code.toLowerCase() == "assign" || code.toLowerCase() == "reassign") {
return MyColors.orange;

@ -1,5 +1,6 @@
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/date_uitl.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -7,6 +8,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_model.dart';
import 'package:mohem_flutter_app/ui/work_list/sheets/delegate_sheet.dart';
import 'package:mohem_flutter_app/ui/work_list/sheets/selected_item_sheet.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
@ -109,6 +111,18 @@ class ActionsFragment extends StatelessWidget {
}).expanded,
Container(width: 1, height: 30, color: MyColors.lightGreyEFColor),
LocaleKeys.delegate.tr().toText12(color: MyColors.gradiantEndColor).center.paddingOnly(top: 6, bottom: 6).onPress(() {
if (actionHistory.uSERNAME == AppState().memberInformationList?.eMPLOYEENUMBER) {
showMyBottomSheet(context,
callBackFunc: voidCallback,
child: DelegateSheet(
title: LocaleKeys.delegate.tr(),
apiMode: "DELEGATE",
notificationID: notificationID,
actionHistoryList: actionHistoryList,
callBackFunc: voidCallback,
));
return;
}
showMyBottomSheet(
context,
callBackFunc: voidCallback,
@ -132,7 +146,10 @@ class ActionsFragment extends StatelessWidget {
String getActionDuration(int index) {
if (actionHistoryList[index].aCTIONCODE == "SUBMIT") {
return "";
} else if(actionHistoryList[index].aCTIONCODE == "PENDING") {
} else if (actionHistoryList[index].aCTIONCODE == "PENDING") {
if (actionHistoryList[++index].nOTIFICATIONDATE!.isEmpty) {
return "";
}
DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[++index].nOTIFICATIONDATE!);
Duration duration = DateTime.now().difference(dateTimeFrom);
return "Action duration: " + DateUtil.formatDuration(duration);

@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mohem_flutter_app/api/chat/chat_provider_model.dart';
import 'package:mohem_flutter_app/api/chat/chat_api_client.dart';
import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
@ -88,7 +88,12 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
void fetchChatUser({bool isNeedLoading = true}) async {
try {
Utils.showLoading(context);
chatUsersList = await ChatProviderModel().getChatMemberFromSearch(searchText, int.parse(AppState().chatDetails!.response!.id.toString()));
chatUsersList = await ChatApiClient().getChatMemberFromSearch(
searchText,
int.parse(
AppState().chatDetails!.response!.id.toString(),
),
);
Utils.hideLoading(context);
setState(() {});
} catch (e) {
@ -236,7 +241,6 @@ class _SearchEmployeeBottomSheetState extends State<SearchEmployeeBottomSheet> {
arguments: {"targetUser": chatUsersList![index], "isNewChat": true},
);
},
),
);
},

Loading…
Cancel
Save