Developing Repost/Share System in a Mobile App
Repost within app and share outside — technically different tasks, though button is one. Internal repost — publish someone else's content in your feed with attribution. External share — transfer content to another app via system share sheet. Usually both needed.
Internal Repost: Data Model
Two approaches:
1. Copy content — new post with field reposted_from_id. Display simplicity, but when original edited, copy becomes stale.
2. Link to original — post with repost_of_id, body not copied, fetched on request. When original deleted, repost shows "Original deleted." Telegram and Twitter/X use exactly this approach.
Second approach is correct. In user's feed, repost renders as embedded original card inside reposter's bubble.
Display in Feed
// iOS — post cell with embedded card
if let repostOf = post.repostOf {
// Draw RepostCardView inside PostCell
let repostCard = RepostCardView(post: repostOf)
contentStack.addArrangedSubview(repostCard)
}
Embedded card — UIView with rounded corners, CALayer.borderColor stroke, original author's avatar and name. Important: no infinite nesting — repost of repost shows only one nesting level (original card).
On Compose: if (post.repostOf != null) EmbeddedPostCard(post = post.repostOf).
Counter and Uniqueness
Table reposts (user_id, original_post_id, UNIQUE) — user can repost original once. Repost button after press becomes active (highlighted), repeat press — cancels repost. Counter reposts_count in original post table.
External Share
iOS — UIActivityViewController:
let items: [Any] = [postText, URL(string: deeplink)!]
let vc = UIActivityViewController(activityItems: items, applicationActivities: nil)
// On iPad need popoverPresentationController
vc.popoverPresentationController?.sourceView = shareButton
present(vc, animated: true)
For sharing post image — render UIView to UIImage via UIGraphicsImageRenderer and add to activityItems.
Android — Intent.ACTION_SEND:
val intent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "$postText\n$deeplinkUrl")
}
startActivity(Intent.createChooser(intent, "Share"))
For images — Intent.ACTION_SEND with type = "image/*" and URI via FileProvider. Direct file:// URI doesn't work on Android 7+, only content:// via FileProvider.
Flutter — share_plus package:
await Share.shareXFiles([XFile(imagePath)], text: '$postText\n$deeplinkUrl');
Deeplink for Share
External share without deeplink loses meaning. Link should open specific post in app. On iOS — Universal Links (apple-app-site-association on server + NSUserActivityTypes in Info.plist). On Android — App Links (assetlinks.json on server + intent-filter in manifest). If app absent — fallback to web post version.
Workflow
Design repost model → implement API (create/delete repost, counters) → UI embedded card in feed → external share with deeplink → test un-repost and deleted originals display.
Timeline
Internal repost with UI — 1-2 days. External share with deeplink — another 1-2 days. Full system with both modes — 2-3 days with parallel platform development. Cost calculated individually.







