mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-11-08 20:12:39 +01:00
Add ability to copy comments, resolves #454
This commit is contained in:
parent
8b850711ce
commit
ddfc310fde
@ -20,7 +20,6 @@ import android.content.Context
|
||||
import ca.allanwang.kau.utils.copyToClipboard
|
||||
import ca.allanwang.kau.utils.shareText
|
||||
import ca.allanwang.kau.utils.string
|
||||
import ca.allanwang.kau.utils.toast
|
||||
import com.pitchedapps.frost.R
|
||||
import com.pitchedapps.frost.activities.MainActivity
|
||||
import com.pitchedapps.frost.facebook.formattedFbUrl
|
||||
@ -29,19 +28,19 @@ import com.pitchedapps.frost.facebook.formattedFbUrl
|
||||
* Created by Allan Wang on 2017-07-07.
|
||||
*/
|
||||
fun Context.showWebContextMenu(wc: WebContext) {
|
||||
|
||||
var title = wc.url
|
||||
if (wc.isEmpty) return
|
||||
var title = wc.url ?: string(R.string.menu)
|
||||
title = title.substring(title.indexOf("m/") + 1) //just so if defaults to 0 in case it's not .com/
|
||||
if (title.length > 100) title = title.substring(0, 100) + '\u2026'
|
||||
|
||||
val menuItems = WebContextType.values
|
||||
.filter { it.constraint(wc) }
|
||||
|
||||
materialDialogThemed {
|
||||
title(title)
|
||||
items(WebContextType.values.map {
|
||||
if (it == WebContextType.COPY_TEXT && wc.text == null) return@map null
|
||||
this@showWebContextMenu.string(it.textId)
|
||||
}.filterNotNull())
|
||||
items(menuItems.map { string(it.textId) })
|
||||
itemsCallback { _, _, position, _ ->
|
||||
WebContextType[position].onClick(this@showWebContextMenu, wc)
|
||||
menuItems[position].onClick(this@showWebContextMenu, wc)
|
||||
}
|
||||
dismissListener {
|
||||
//showing the dialog interrupts the touch down event, so we must ensure that the viewpager's swipe is enabled
|
||||
@ -50,18 +49,23 @@ fun Context.showWebContextMenu(wc: WebContext) {
|
||||
}
|
||||
}
|
||||
|
||||
class WebContext(val unformattedUrl: String, val text: String?) {
|
||||
val url = unformattedUrl.formattedFbUrl
|
||||
class WebContext(val unformattedUrl: String?, val text: String?) {
|
||||
val url: String? = unformattedUrl?.formattedFbUrl
|
||||
inline val hasUrl get() = unformattedUrl != null
|
||||
inline val hasText get() = text != null
|
||||
inline val isEmpty get() = !hasUrl && !hasText
|
||||
}
|
||||
|
||||
enum class WebContextType(val textId: Int, val onClick: (c: Context, wc: WebContext) -> Unit) {
|
||||
OPEN_LINK(R.string.open_link, { c, wc -> c.launchWebOverlay(wc.unformattedUrl) }),
|
||||
COPY_LINK(R.string.copy_link, { c, wc -> c.copyToClipboard(wc.url) }),
|
||||
COPY_TEXT(
|
||||
R.string.copy_text,
|
||||
{ c, wc -> if (wc.text != null) c.copyToClipboard(wc.text) else c.toast(R.string.no_text) }),
|
||||
SHARE_LINK(R.string.share_link, { c, wc -> c.shareText(wc.url) }),
|
||||
DEBUG_LINK(R.string.debug_link, { c, wc ->
|
||||
enum class WebContextType(
|
||||
val textId: Int,
|
||||
val constraint: (wc: WebContext) -> Boolean,
|
||||
val onClick: (c: Context, wc: WebContext) -> Unit
|
||||
) {
|
||||
OPEN_LINK(R.string.open_link, { it.hasUrl }, { c, wc -> c.launchWebOverlay(wc.unformattedUrl!!) }),
|
||||
COPY_LINK(R.string.copy_link, { it.hasUrl }, { c, wc -> c.copyToClipboard(wc.url) }),
|
||||
COPY_TEXT(R.string.copy_text, { it.hasText }, { c, wc -> c.copyToClipboard(wc.text) }),
|
||||
SHARE_LINK(R.string.share_link, { it.hasUrl }, { c, wc -> c.shareText(wc.url) }),
|
||||
DEBUG_LINK(R.string.debug_link, { it.hasUrl }, { c, wc ->
|
||||
c.materialDialogThemed {
|
||||
title(R.string.debug_link)
|
||||
content(R.string.debug_link_desc)
|
||||
@ -69,8 +73,8 @@ enum class WebContextType(val textId: Int, val onClick: (c: Context, wc: WebCont
|
||||
onPositive { _, _ ->
|
||||
c.sendFrostEmail(R.string.debug_link_subject) {
|
||||
message = c.string(R.string.debug_link_content)
|
||||
addItem("Unformatted url", wc.unformattedUrl)
|
||||
addItem("Formatted url", wc.url)
|
||||
addItem("Unformatted url", wc.unformattedUrl!!)
|
||||
addItem("Formatted url", wc.url!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,10 +76,9 @@ class FrostJSI(val web: FrostWebView) {
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun contextMenu(url: String, text: String?) {
|
||||
if (!text.isIndependent) return
|
||||
fun contextMenu(url: String?, text: String?) {
|
||||
//url will be formatted through webcontext
|
||||
web.post { context.showWebContextMenu(WebContext(url, text)) }
|
||||
web.post { context.showWebContextMenu(WebContext(url.takeIf { it.isIndependent }, text)) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,15 @@
|
||||
"use strict";
|
||||
(function () {
|
||||
var longClick = false;
|
||||
var _frostCopyComment = function (e, target) {
|
||||
if (!target.hasAttribute('data-commentid')) {
|
||||
return false;
|
||||
}
|
||||
var text = target.innerText;
|
||||
console.log("Copy comment " + text);
|
||||
Frost.contextMenu(null, text);
|
||||
return true;
|
||||
};
|
||||
var _frostCopyPost = function (e, target) {
|
||||
if (target.tagName !== 'A') {
|
||||
return false;
|
||||
@ -55,12 +64,12 @@
|
||||
Frost.contextMenu(url, text);
|
||||
return true;
|
||||
};
|
||||
var handlers = [_frostCopyPost, _frostImage];
|
||||
var handlers = [_frostCopyComment, _frostCopyPost, _frostImage];
|
||||
var _frostAContext = function (e) {
|
||||
Frost.longClick(true);
|
||||
longClick = true;
|
||||
var target = e.target || e.currentTarget || e.srcElement;
|
||||
if (!(target instanceof Element)) {
|
||||
if (!(target instanceof HTMLElement)) {
|
||||
console.log("No element found");
|
||||
return;
|
||||
}
|
||||
|
@ -9,7 +9,17 @@
|
||||
/**
|
||||
* Given event and target, return true if handled and false otherwise.
|
||||
*/
|
||||
type EventHandler = (e: Event, target: Element) => Boolean
|
||||
type EventHandler = (e: Event, target: HTMLElement) => Boolean
|
||||
|
||||
const _frostCopyComment: EventHandler = (e, target) => {
|
||||
if (!target.hasAttribute('data-commentid')) {
|
||||
return false;
|
||||
}
|
||||
const text = target.innerText;
|
||||
console.log(`Copy comment ${text}`);
|
||||
Frost.contextMenu(null, text);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Posts should click a tag, with two parents up being div.story_body_container
|
||||
@ -26,7 +36,7 @@
|
||||
if (!parent2 || !parent2.classList.contains('story_body_container')) {
|
||||
return false;
|
||||
}
|
||||
const url = target.getAttribute('href')!;
|
||||
const url = target.getAttribute('href');
|
||||
const text = parent1.innerText;
|
||||
console.log(`Copy post ${url} ${text}`);
|
||||
Frost.contextMenu(url, text);
|
||||
@ -42,11 +52,11 @@
|
||||
}
|
||||
}
|
||||
if (element.tagName !== 'A') {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
const url = element.getAttribute('href');
|
||||
if (!url || url === '#') {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
const text = (<HTMLElement>element.parentElement).innerText;
|
||||
// Check if image item exists, first in children and then in parent
|
||||
@ -58,7 +68,7 @@
|
||||
const imageUrl = (<String>window.getComputedStyle(image, null).backgroundImage).trim().slice(4, -1);
|
||||
console.log(`Context image: ${imageUrl}`);
|
||||
Frost.loadImage(imageUrl, text);
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
// Check if true img exists
|
||||
const img = element.querySelector("img[src*=scontent]");
|
||||
@ -66,14 +76,14 @@
|
||||
const imgUrl = img.src;
|
||||
console.log(`Context img: ${imgUrl}`);
|
||||
Frost.loadImage(imgUrl, text);
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
console.log(`Context content ${url} ${text}`);
|
||||
Frost.contextMenu(url, text);
|
||||
return true
|
||||
return true;
|
||||
};
|
||||
|
||||
const handlers = [_frostCopyPost, _frostImage];
|
||||
const handlers = [_frostCopyComment, _frostCopyPost, _frostImage];
|
||||
|
||||
const _frostAContext = (e: Event) => {
|
||||
Frost.longClick(true);
|
||||
@ -83,7 +93,7 @@
|
||||
* Commonality; check for valid target
|
||||
*/
|
||||
const target = e.target || e.currentTarget || e.srcElement;
|
||||
if (!(target instanceof Element)) {
|
||||
if (!(target instanceof HTMLElement)) {
|
||||
console.log("No element found");
|
||||
return
|
||||
}
|
||||
|
2
app/src/web/assets/typings/frost.d.ts
vendored
2
app/src/web/assets/typings/frost.d.ts
vendored
@ -5,7 +5,7 @@ declare interface FrostJSI {
|
||||
|
||||
reloadBaseUrl(animate: boolean)
|
||||
|
||||
contextMenu(url: string, text: string | null)
|
||||
contextMenu(url: string | null, text: string | null)
|
||||
|
||||
longClick(start: boolean)
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
## v2.2.2
|
||||
* New marketplace shortcut
|
||||
* Fix crash when internet disconnects (may still need app restart)
|
||||
* Improve JS code
|
||||
|
||||
## v2.2.1
|
||||
* Update theme
|
||||
|
Loading…
Reference in New Issue
Block a user