Skip to content

Commit 53ddb68

Browse files
anhanh11001iamareebjamal
authored andcommitted
feat: Add sharing ticket feature (#1702)
Detail: - Create a bitmap from container view of single ticket - Turn bitmap into an URL and then share it to another app Fixes: #1699
1 parent b07cd45 commit 53ddb68

File tree

6 files changed

+84
-1
lines changed

6 files changed

+84
-1
lines changed

app/src/main/java/org/fossasia/openevent/general/order/OrderDetailsFragment.kt

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
package org.fossasia.openevent.general.order
22

3+
import android.content.Intent
4+
import android.graphics.Bitmap
5+
import android.graphics.Canvas
6+
import android.net.Uri
37
import android.os.Bundle
48
import android.view.LayoutInflater
59
import android.view.MenuItem
610
import android.view.View
711
import android.view.ViewGroup
12+
import android.view.Menu
13+
import android.view.MenuInflater
14+
import androidx.core.content.FileProvider
815
import androidx.core.view.isVisible
916
import androidx.fragment.app.Fragment
1017
import androidx.lifecycle.Observer
1118
import androidx.recyclerview.widget.LinearLayoutManager
1219
import androidx.navigation.Navigation.findNavController
1320
import androidx.navigation.fragment.navArgs
1421
import androidx.recyclerview.widget.LinearSnapHelper
22+
import androidx.recyclerview.widget.RecyclerView
1523
import kotlinx.android.synthetic.main.fragment_order_details.view.orderDetailCoordinatorLayout
1624
import kotlinx.android.synthetic.main.fragment_order_details.view.orderDetailsRecycler
1725
import kotlinx.android.synthetic.main.fragment_order_details.view.progressBar
26+
import kotlinx.android.synthetic.main.item_card_order_details.view.orderDetailCardView
27+
import org.fossasia.openevent.general.BuildConfig
1828
import org.fossasia.openevent.general.R
1929
import org.fossasia.openevent.general.event.EventDetailsFragmentArgs
2030
import org.fossasia.openevent.general.utils.Utils.getAnimFade
@@ -23,6 +33,9 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
2333
import timber.log.Timber
2434
import org.fossasia.openevent.general.utils.Utils.setToolbar
2535
import org.jetbrains.anko.design.longSnackbar
36+
import org.jetbrains.anko.design.snackbar
37+
import java.io.File
38+
import java.io.FileOutputStream
2639

2740
class OrderDetailsFragment : Fragment() {
2841

@@ -69,7 +82,20 @@ class OrderDetailsFragment : Fragment() {
6982
linearLayoutManager = LinearLayoutManager(context)
7083
linearLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
7184
rootView.orderDetailsRecycler.layoutManager = linearLayoutManager
72-
LinearSnapHelper().attachToRecyclerView(rootView.orderDetailsRecycler)
85+
val snapHelper = LinearSnapHelper()
86+
snapHelper.attachToRecyclerView(rootView.orderDetailsRecycler)
87+
rootView.orderDetailsRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
88+
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
89+
super.onScrollStateChanged(recyclerView, newState)
90+
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
91+
val centerView = snapHelper.findSnapView(linearLayoutManager)
92+
centerView?.let {
93+
val itemPosition = linearLayoutManager.getPosition(it)
94+
orderDetailsViewModel.currentTicketPosition = itemPosition
95+
}
96+
}
97+
}
98+
})
7399

74100
val eventDetailsListener = object : OrderDetailsRecyclerAdapter.EventDetailsListener {
75101
override fun onClick(eventID: Long) {
@@ -101,13 +127,59 @@ class OrderDetailsFragment : Fragment() {
101127
return rootView
102128
}
103129

130+
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
131+
inflater.inflate(R.menu.order_detail, menu)
132+
super.onCreateOptionsMenu(menu, inflater)
133+
}
134+
104135
override fun onOptionsItemSelected(item: MenuItem): Boolean {
105136
return when (item.itemId) {
106137
android.R.id.home -> {
107138
activity?.onBackPressed()
108139
true
109140
}
141+
R.id.share_ticket -> {
142+
shareCurrentTicket()
143+
true
144+
}
110145
else -> super.onOptionsItemSelected(item)
111146
}
112147
}
148+
149+
private fun shareCurrentTicket() {
150+
val currentTicketViewHolder =
151+
rootView.orderDetailsRecycler.findViewHolderForAdapterPosition(orderDetailsViewModel.currentTicketPosition)
152+
if (currentTicketViewHolder != null && currentTicketViewHolder is OrderDetailsViewHolder) {
153+
val bitmap = getBitmapFromView(currentTicketViewHolder.itemView.rootView.orderDetailCardView)
154+
val bitmapUri = getBitmapUri(bitmap)
155+
if (bitmapUri == null) {
156+
rootView.snackbar(getString(R.string.fail_sharing_ticket))
157+
return
158+
}
159+
val intent = Intent(Intent.ACTION_SEND)
160+
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
161+
intent.type = "image/png"
162+
intent.putExtra(Intent.EXTRA_STREAM, bitmapUri)
163+
startActivity(intent)
164+
} else {
165+
rootView.snackbar(getString(R.string.fail_sharing_ticket))
166+
}
167+
}
168+
169+
private fun getBitmapUri(bitmap: Bitmap): Uri? {
170+
val myContext = context ?: return null
171+
val file = File(myContext.cacheDir, "shared_image.png")
172+
return FileOutputStream(file)
173+
.use { fileOutputStream ->
174+
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream)
175+
FileProvider.getUriForFile(myContext, BuildConfig.APPLICATION_ID + ".provider", file)
176+
}
177+
}
178+
179+
private fun getBitmapFromView(view: View): Bitmap {
180+
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
181+
val canvas = Canvas(bitmap)
182+
view.draw(canvas)
183+
return bitmap
184+
}
113185
}

app/src/main/java/org/fossasia/openevent/general/order/OrderDetailsViewModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class OrderDetailsViewModel(
2828
val attendees: LiveData<List<Attendee>> = mutableAttendees
2929
private val mutableProgress = MutableLiveData<Boolean>()
3030
val progress: LiveData<Boolean> = mutableProgress
31+
var currentTicketPosition: Int = 0
3132

3233
fun loadEvent(id: Long) {
3334
if (id.equals(-1)) {

app/src/main/res/layout-land/item_card_order_details.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
app:cardElevation="@dimen/card_elevation"
1515
android:elevation="@dimen/card_elevation"
1616
android:paddingBottom="@dimen/padding_extra_small"
17+
android:id="@+id/orderDetailCardView"
1718
android:foreground="?android:attr/selectableItemBackground">
1819
<LinearLayout
1920
android:layout_width="match_parent"

app/src/main/res/layout/item_card_order_details.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
android:layout_width="match_parent"
55
android:layout_height="match_parent">
66
<androidx.cardview.widget.CardView
7+
android:id="@+id/orderDetailCardView"
78
android:layout_width="match_parent"
89
android:layout_height="wrap_content"
910
android:layout_margin="@dimen/layout_margin_large"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<menu xmlns:android="http://schemas.android.com/apk/res/android">
3+
<item
4+
android:id="@+id/share_ticket"
5+
android:title="@string/share_ticket"/>
6+
</menu>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@
240240
<string name="order_fail_message">Unable to create Order!</string>
241241
<string name="payment_not_complete_message">Payment not completed!</string>
242242
<string name="error_fetching_attendee_details_message">Error fetching attendee details</string>
243+
<string name="share_ticket">Share Ticket</string>
244+
<string name="fail_sharing_ticket">Fail to share ticket</string>
243245

244246
<!--snackbar messages-->
245247
<string name="logged_in_automatically">Logged in Automatically!</string>

0 commit comments

Comments
 (0)