Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Awful.apk/src/main/assets/javascript/thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@ function showPostMenu(postMenu) {
postMenu.getAttribute('userid'),
postMenu.getAttribute('lastreadurl'),
postMenu.hasAttribute('editable'),
postMenu.hasAttribute('modControls'),
postMenu.getAttribute('data-role'),
postMenu.hasAttribute('isPlat'),
avatar ? avatar.getAttribute('src') : null
Expand Down
2 changes: 1 addition & 1 deletion Awful.apk/src/main/assets/mustache/post.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{{#avatarText}}<aside aria-hidden="true" class="postinfo-title">{{avatarText}}</aside>{{/avatarText}}
</section >
</div>
<nav aria-label="post menu" role="button" class="postmenu" username="{{username}}" userid="{{userID}}" lastreadurl="{{lastReadUrl}}" {{#editable}}editable{{/editable}} {{#role}}data-role="{{role}}"{{/role}} {{#plat}}isPlat{{/plat}} ></nav>
<nav aria-label="post menu" role="button" class="postmenu" username="{{username}}" userid="{{userID}}" lastreadurl="{{lastReadUrl}}" {{#editable}}editable{{/editable}} {{#modControls}}modControls{{/modControls}} {{#role}}data-role="{{role}}"{{/role}} {{#plat}}isPlat{{/plat}} ></nav>
</header>
<div class="postseparator"></div>
<section class="postcontent">
Expand Down
29 changes: 29 additions & 0 deletions Awful.apk/src/main/java/com/ferg/awfulapp/NavigationEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.ferg.awfulapp.search.SearchFilter
import com.ferg.awfulapp.search.SearchFragment
import com.ferg.awfulapp.thread.AwfulURL
import com.ferg.awfulapp.users.LepersColonyFragment
import com.ferg.awfulapp.users.ModQueueRequestFragment
import com.ferg.awfulapp.util.AwfulUtils
import com.ferg.awfulapp.util.tryGetIntExtra
import timber.log.Timber
Expand Down Expand Up @@ -135,6 +136,24 @@ sealed class NavigationEvent(private val extraTypeId: String) {
}
}

/**
* Show the modqueue probation/ban request page for a post ([ban] selects which), targeting
* the [userId] who made the post [postId] in thread [threadId].
*/
data class ModQueueRequest(val ban: Boolean, val userId: Int, val postId: Int, val threadId: Int) : NavigationEvent(TYPE_MODQUEUE_REQUEST) {

override fun activityIntent(context: Context) =
BasicActivity.intentFor(ModQueueRequestFragment::class.java, context,
context.getString(if (ban) R.string.mod_ban_request_title else R.string.mod_probation_request_title))

override val addDataToIntent: Intent.() -> Unit = {
putExtra(KEY_MODQUEUE_IS_BAN, ban)
putExtra(Constants.PARAM_USER_ID, userId)
putExtra(Constants.PARAM_POST_ID, postId)
putExtra(Constants.PARAM_THREAD_ID, threadId)
}
}


/**
* Build an Intent for this NavigationEvent.
Expand Down Expand Up @@ -168,8 +187,10 @@ sealed class NavigationEvent(private val extraTypeId: String) {
private const val TYPE_COMPOSE_PRIVATE_MESSAGE = "nav_compose_private_message"
private const val TYPE_ANNOUNCEMENTS = "nav_announcements"
private const val TYPE_LEPERS_COLONY = "nav_rap_sheet"
private const val TYPE_MODQUEUE_REQUEST = "nav_modqueue_request"

private const val KEY_SEARCH_FILTERS = "key_search_filters"
private const val KEY_MODQUEUE_IS_BAN = "key_modqueue_is_ban"

private fun Context.intentFor(clazz: Class<out Activity>): Intent = Intent().setClass(this, clazz)

Expand Down Expand Up @@ -211,6 +232,12 @@ sealed class NavigationEvent(private val extraTypeId: String) {
userId = getIntExtra(Constants.PARAM_USER_ID),
page = getIntExtra(Constants.PARAM_PAGE) ?: LepersColonyFragment.FIRST_PAGE
)
TYPE_MODQUEUE_REQUEST -> ModQueueRequest(
ban = getBooleanExtra(KEY_MODQUEUE_IS_BAN, false),
userId = getIntExtra(Constants.PARAM_USER_ID)!!,
postId = getIntExtra(Constants.PARAM_POST_ID)!!,
threadId = getIntExtra(Constants.PARAM_THREAD_ID)!!
)
else -> {
Timber.w("Couldn't parse Intent as NavigationEvent - event key: ${getStringExtra(EVENT_EXTRA_KEY)}")
MainActivity
Expand Down Expand Up @@ -244,6 +271,8 @@ sealed class NavigationEvent(private val extraTypeId: String) {
ForumIndex
isBanlist ->
LepersColony(id.toInt())
isModQueueRequest ->
ModQueueRequest(isBanRequest, id.toInt(), targetPostId.toInt(), threadId.toInt())
else -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ public boolean shouldOverrideUrlLoading(WebView aView, String aUrl) {
case BANLIST:
navigate(new NavigationEvent.LepersColony((int) aLink.getId()));
break;
case MODQUEUE_REQUEST:
navigate(new NavigationEvent.ModQueueRequest(aLink.isBanRequest(),
(int) aLink.getId(), (int) aLink.getTargetPostId(), (int) aLink.getThreadId()));
break;
case INDEX:
navigate(NavigationEvent.ForumIndex.INSTANCE);
break;
Expand Down Expand Up @@ -1180,14 +1184,17 @@ public void onMoreClick(
final String aUserId,
final String lastReadUrl,
final boolean editable,
final boolean hasModControls,
final String posterRole,
final boolean isPlat,
final String avatarUrl) {

PostContextMenu postActions = PostContextMenu.newInstance(getThreadId(),
Integer.parseInt(aPostId),
Integer.parseInt(lastReadUrl),
editable, aUsername,
editable,
hasModControls,
aUsername,
Integer.parseInt(aUserId),
isPlat,
posterRole,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class Constants {
public static final String FUNCTION_RATE_THREAD = BASE_URL + "/threadrate.php";
public static final String FUNCTION_MISC = BASE_URL + "/misc.php";
public static final String FUNCTION_REPORT = BASE_URL + "/modalert.php";
public static final String FUNCTION_MODQUEUE = BASE_URL + "/modqueue.php";
public static final String FUNCTION_POSTINGS = BASE_URL + "/postings.php";
public static final String FUNCTION_NEW_THREAD = BASE_URL + "/newthread.php";

Expand All @@ -62,6 +63,7 @@ public class Constants {
public static final String PATH_BOOKMARKS = "bookmarkthreads.php";
public static final String PATH_USERCP = "usercp.php";
public static final String PATH_BANLIST = "banlist.php";
public static final String PATH_MODQUEUE = "modqueue.php";

public static final String ACTION_PROFILE = "getinfo";
public static final String ACTION_SEARCH_POST_HISTORY = "do_search_posthistory";
Expand All @@ -72,6 +74,8 @@ public class Constants {
public static final String ACTION_QUERY = "query";
public static final String ACTION_RESULTS = "results";
public static final String ACTION_TOGGLE_THREAD_LOCKED = "openclosethread";
public static final String ACTION_REQUEST_PROBATION = "request_probation";
public static final String ACTION_REQUEST_BAN = "request_ban";

public static final String PARAM_USER_ID = "userid";
public static final String PARAM_USERNAME = "username";
Expand All @@ -87,6 +91,7 @@ public class Constants {
public static final String PARAM_PRIVATE_MESSAGE_ID = "privatemessageid";
public static final String PARAM_VOTE = "vote";
public static final String PARAM_POST_ID = "postid";
public static final String PARAM_TARGET_POST_ID = "tpostid";
public static final String PARAM_USERLIST = "userlist";
public static final String PARAM_FORMKEY = "formkey";
public static final String PARAM_FORM_COOKIE = "form_cookie";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.ferg.awfulapp.popupmenu

import android.os.Bundle
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.ferg.awfulapp.AwfulActivity
import com.ferg.awfulapp.NavigationEvent
import com.ferg.awfulapp.R
import com.ferg.awfulapp.ThreadDisplayFragment
import com.ferg.awfulapp.popupmenu.ModeratePostMenu.ModerateMenuAction.EDIT_POST
import com.ferg.awfulapp.popupmenu.ModeratePostMenu.ModerateMenuAction.REQUEST_BAN
import com.ferg.awfulapp.popupmenu.ModeratePostMenu.ModerateMenuAction.REQUEST_PROBATION
import com.ferg.awfulapp.thread.AwfulMessage

/**
* Context menu with moderation actions for someone else's post.
*
* Shows an edit option when the post is editable by the current user, plus the modqueue
* probation/ban request options when the post carries modqueue controls.
*/
class ModeratePostMenu : BasePopupMenu<ModeratePostMenu.ModerateMenuAction>() {

private var threadId = 0
private var postId = 0
private var posterUserId = 0
private var editable = false
private var hasModControls = false

companion object {
@JvmField
val TAG: String = ModeratePostMenu::class.java.simpleName

private const val ARG_THREAD_ID = "threadId"
private const val ARG_POST_ID = "postId"
private const val ARG_POSTER_USER_ID = "posterUserId"
private const val ARG_EDITABLE = "editable"
private const val ARG_HAS_MOD_CONTROLS = "hasModControls"

/**
* Get a moderation menu for a post, where [editable] adds the edit option and
* [hasModControls] adds the modqueue probation/ban request options.
*/
@JvmStatic
fun newInstance(threadId: Int, postId: Int, posterUserId: Int, editable: Boolean, hasModControls: Boolean) =
ModeratePostMenu().apply {
arguments = Bundle().apply {
putInt(ARG_THREAD_ID, threadId)
putInt(ARG_POST_ID, postId)
putInt(ARG_POSTER_USER_ID, posterUserId)
putBoolean(ARG_EDITABLE, editable)
putBoolean(ARG_HAS_MOD_CONTROLS, hasModControls)
}
}
}

override fun init(args: Bundle) = with(args) {
threadId = getInt(ARG_THREAD_ID)
postId = getInt(ARG_POST_ID)
posterUserId = getInt(ARG_POSTER_USER_ID)
editable = getBoolean(ARG_EDITABLE)
hasModControls = getBoolean(ARG_HAS_MOD_CONTROLS)
}

override fun generateMenuItems() =
mutableListOf<ModerateMenuAction>()
.apply { if (editable) add(EDIT_POST) }
.apply { if (hasModControls) { add(REQUEST_PROBATION); add(REQUEST_BAN) } }

override fun getMenuLabel(action: ModerateMenuAction): String = getString(action.menuLabelRes)

override fun getTitle(): String = getString(R.string.action_moderate_post)

override fun onActionClicked(action: ModerateMenuAction) {
when (action) {
EDIT_POST ->
(targetFragment as? ThreadDisplayFragment)
?.displayPostReplyDialog(threadId, postId, AwfulMessage.TYPE_EDIT)
REQUEST_PROBATION ->
navigateTo(NavigationEvent.ModQueueRequest(ban = false, userId = posterUserId, postId = postId, threadId = threadId))
REQUEST_BAN ->
navigateTo(NavigationEvent.ModQueueRequest(ban = true, userId = posterUserId, postId = postId, threadId = threadId))
}
}

private fun navigateTo(event: NavigationEvent) {
(activity as AwfulActivity?)?.navigate(event)
}

enum class ModerateMenuAction(
@DrawableRes private val iconResId: Int,
@StringRes val menuLabelRes: Int
) : AwfulAction {

EDIT_POST(R.drawable.ic_create_dark, R.string.action_edit_post),
REQUEST_PROBATION(R.drawable.ic_history_dark_24dp, R.string.action_request_probation),
REQUEST_BAN(R.drawable.ic_gavel_dark_24dp, R.string.action_request_ban);

override fun getIconId() = iconResId
// labels are resolved from menuLabelRes in getMenuLabel above, where a Context is available
override fun getMenuLabel() = ""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static com.ferg.awfulapp.popupmenu.PostContextMenu.PostMenuAction.IGNORE_USER;
import static com.ferg.awfulapp.popupmenu.PostContextMenu.PostMenuAction.MARK_LAST_SEEN;
import static com.ferg.awfulapp.popupmenu.PostContextMenu.PostMenuAction.MARK_USER;
import static com.ferg.awfulapp.popupmenu.PostContextMenu.PostMenuAction.MODERATE;
import static com.ferg.awfulapp.popupmenu.PostContextMenu.PostMenuAction.RAP_SHEET;
import static com.ferg.awfulapp.popupmenu.PostContextMenu.PostMenuAction.REPORT_POST;
import static com.ferg.awfulapp.popupmenu.PostContextMenu.PostMenuAction.SEND_PM;
Expand All @@ -42,6 +43,7 @@ public class PostContextMenu extends BasePopupMenu<PostContextMenu.PostMenuActio

private static final String ARG_POSTER_USER_ID = "posterUserId";
private static final String ARG_EDITABLE = "editable";
private static final String ARG_HAS_MOD_CONTROLS = "hasModControls";
private static final String ARG_POSTER_HAS_PLAT = "posterHasPlat";
private static final String ARG_POSTER_ROLE = "posterRole";
private static final String ARG_THREAD_ID = "threadId";
Expand All @@ -53,6 +55,7 @@ public class PostContextMenu extends BasePopupMenu<PostContextMenu.PostMenuActio

private int posterUserId;
private boolean editable;
private boolean hasModControls;
private boolean posterHasPlat;
private boolean posterHasRole;
private boolean posterIsUnreportable;
Expand All @@ -71,6 +74,7 @@ public class PostContextMenu extends BasePopupMenu<PostContextMenu.PostMenuActio
* @param postId the ID of the post the menu is for
* @param lastReadCode the ID code used when marking a post as the last-read (see {@link ThreadDisplayFragment#markLastRead(int)})
* @param editable true if the post can be edited by you
* @param hasModControls true if the post has moderator queue controls (i.e. you can probate/ban for it)
* @param posterUsername the username of the post creator
* @param posterUserId the user ID of the post creator
* @param posterHasPlat true if the post creator has a platinum account
Expand All @@ -82,6 +86,7 @@ public static PostContextMenu newInstance(int threadId,
int postId,
int lastReadCode,
boolean editable,
boolean hasModControls,
@NonNull String posterUsername,
int posterUserId,
boolean posterHasPlat,
Expand All @@ -93,6 +98,7 @@ public static PostContextMenu newInstance(int threadId,

args.putInt(ARG_POSTER_USER_ID, posterUserId);
args.putBoolean(ARG_EDITABLE, editable);
args.putBoolean(ARG_HAS_MOD_CONTROLS, hasModControls);
args.putBoolean(ARG_POSTER_HAS_PLAT, posterHasPlat);
args.putString(ARG_POSTER_ROLE, posterRole);
args.putInt(ARG_THREAD_ID, threadId);
Expand All @@ -112,6 +118,7 @@ public static PostContextMenu newInstance(int threadId,
void init(@NonNull Bundle args) {
posterUserId = args.getInt(ARG_POSTER_USER_ID);
editable = args.getBoolean(ARG_EDITABLE);
hasModControls = args.getBoolean(ARG_HAS_MOD_CONTROLS);
posterHasPlat = args.getBoolean(ARG_POSTER_HAS_PLAT);
String posterRole = args.getString(ARG_POSTER_ROLE, "");
posterHasRole = !posterRole.isEmpty();
Expand All @@ -135,7 +142,7 @@ List<PostMenuAction> generateMenuItems() {
List<PostMenuAction> awfulActions = new ArrayList<>();

awfulActions.add(PostMenuAction.QUOTE);
if (editable) {
if (editable && ownPost) {
awfulActions.add(EDIT);
}
awfulActions.add(MARK_LAST_SEEN);
Expand All @@ -158,6 +165,9 @@ List<PostMenuAction> generateMenuItems() {
awfulActions.add(prefs.blockedAvatarUrls.contains(posterAvatarUrl) ?
SHOW_AVATAR : HIDE_AVATAR);
}
if (!ownPost && (editable || hasModControls)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean if we're going for parity, mod tools should be available for your own posts as well. There have been some comedy self-probations in the past that I can remember.

awfulActions.add(MODERATE);
}
return awfulActions;
}

Expand Down Expand Up @@ -212,13 +222,22 @@ void onActionClicked(@NonNull PostMenuAction action) {
case HIDE_AVATAR:
parent.toggleAvatar(posterAvatarUrl);
break;
case MODERATE:
ModeratePostMenu moderateMenu = ModeratePostMenu.newInstance(threadId, postId,
posterUserId, editable, hasModControls);
moderateMenu.setTargetFragment(parent, -1);
moderateMenu.show(parent.getParentFragmentManager(), ModeratePostMenu.TAG);
break;
}
}


@NonNull
@Override
String getMenuLabel(@NonNull PostMenuAction action) {
if (action == MODERATE) {
return getString(R.string.action_moderate_post);
}
// need to add the post's username to some of these
return String.format(action.getMenuLabel(), posterUsername);
}
Expand All @@ -244,7 +263,9 @@ public enum PostMenuAction implements AwfulAction {
RAP_SHEET(R.drawable.ic_gavel_dark_24dp, "%s's rap sheet"),
IGNORE_USER(R.drawable.ic_ignore_dark, "Ignore %s"),
SHOW_AVATAR(R.drawable.ic_visibility_dark, "Show avatar of %s"),
HIDE_AVATAR(R.drawable.ic_ignore_dark, "Hide avatar of %s");
HIDE_AVATAR(R.drawable.ic_ignore_dark, "Hide avatar of %s"),
// label comes from R.string.action_moderate_post, see #getMenuLabel
MODERATE(R.drawable.ic_info_dark, "");

final int iconId;
@NonNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ private static String[] arrayOfKeys(@NonNull Map<String, ?> map) {
sPostProjectionMap.put(AwfulPost.IS_IGNORED, AwfulPost.IS_IGNORED);
sPostProjectionMap.put(AwfulPost.PREVIOUSLY_READ, AwfulPost.PREVIOUSLY_READ);
sPostProjectionMap.put(AwfulPost.EDITABLE, AwfulPost.EDITABLE);
sPostProjectionMap.put(AwfulPost.HAS_MOD_CONTROLS, AwfulPost.HAS_MOD_CONTROLS);
sPostProjectionMap.put(AwfulPost.IS_OP, AwfulPost.IS_OP);
sPostProjectionMap.put(AwfulPost.IS_PLAT, AwfulPost.IS_PLAT);
sPostProjectionMap.put(AwfulPost.ROLE, AwfulPost.ROLE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public class DatabaseHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "awful.db";
private static final int DATABASE_VERSION = 39;
private static final int DATABASE_VERSION = 40;

static final String TABLE_FORUM = "forum";
public static final String TABLE_THREADS = "threads";
Expand Down Expand Up @@ -109,6 +109,7 @@ private void createPostTable(SQLiteDatabase aDb) {
AwfulPost.IS_IGNORED + " INTEGER," +
AwfulPost.PREVIOUSLY_READ + " INTEGER," +
AwfulPost.EDITABLE + " INTEGER," +
AwfulPost.HAS_MOD_CONTROLS + " INTEGER," +
AwfulPost.IS_OP + " INTEGER," +
AwfulPost.IS_PLAT + " INTEGER," +
AwfulPost.ROLE + " VARCHAR," +
Expand Down Expand Up @@ -215,6 +216,8 @@ public void onUpgrade(SQLiteDatabase aDb, int aOldVersion, int aNewVersion) {
createPostTable(aDb);
case 38:
aDb.execSQL("ALTER TABLE " + TABLE_THREADS + " ADD COLUMN " + AwfulThread.LAST_POST_DATE + " INTEGER DEFAULT 0");
case 39:
aDb.execSQL("ALTER TABLE " + TABLE_POSTS + " ADD COLUMN " + AwfulPost.HAS_MOD_CONTROLS + " INTEGER DEFAULT 0");
break;//make sure to keep this break statement on the last case of this switch
default:
wipeRecreateTables(aDb);
Expand Down
Loading