aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/mygram/droid/TileAdapter.java
blob: cf80f51e0514cff59f390910a68f421118790cbf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * mygram-droid: Android TV client for Foldergram.
 * Copyright (C) 2026 Danilo M. <danix@danix.xyz>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 */

package mygram.droid;

import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;

import java.util.List;

/** Thumbnail tiles for rows and grids: posts, folders and the Continue tile. */
final class TileAdapter extends RecyclerView.Adapter<TileAdapter.Holder> {
	static final class Tile {
		final String image, label;
		final int icon, postId;
		final Runnable click;

		/** image or icon is shown; postId is -1 for tiles that are not posts. */
		Tile(String image, String label, int icon, int postId, Runnable click) {
			this.image = image;
			this.label = label;
			this.icon = icon;
			this.postId = postId;
			this.click = click;
		}
	}

	static Tile post(Post p, Runnable click) {
		return new Tile(p.media.get(0).thumbnailUrl, null, 0, p.id, click);
	}

	static final class Holder extends RecyclerView.ViewHolder {
		final ImageView image, heart;
		final TextView label;

		Holder(View v, ImageView image, TextView label, ImageView heart) {
			super(v);
			this.image = image;
			this.label = label;
			this.heart = heart;
		}
	}

	private final List<Tile> tiles;
	private final int widthDp, heightDp;

	TileAdapter(List<Tile> tiles, int widthDp, int heightDp) {
		this.tiles = tiles;
		this.widthDp = widthDp;
		this.heightDp = heightDp;
	}

	@Override
	public Holder onCreateViewHolder(ViewGroup parent, int type) {
		Context c = parent.getContext();
		FrameLayout frame = new FrameLayout(c);
		RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(Ui.dp(c, widthDp), Ui.dp(c, heightDp));
		int m = Ui.dp(c, 12);
		lp.setMargins(m, m, m, m);
		frame.setLayoutParams(lp);
		frame.setBackgroundColor(0xFF222222);
		ImageView image = new ImageView(c);
		frame.addView(image, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.MATCH_PARENT));
		TextView label = Ui.text(c, "", 14);
		label.setShadowLayer(6, 0, 0, Color.BLACK);
		int p = Ui.dp(c, 8);
		label.setPadding(p, p, p, p);
		frame.addView(label, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM));
		ImageView heart = new ImageView(c);
		heart.setImageResource(R.drawable.ic_favorite);
		heart.setColorFilter(Ui.RED);
		heart.setContentDescription("Liked");
		int s = Ui.dp(c, 22);
		FrameLayout.LayoutParams hp = new FrameLayout.LayoutParams(s, s, Gravity.TOP | Gravity.END);
		hp.setMargins(p, p, p, p);
		frame.addView(heart, hp);
		Ui.focusable(frame);
		return new Holder(frame, image, label, heart);
	}

	@Override
	public void onBindViewHolder(Holder h, int position) {
		Tile t = tiles.get(position);
		h.itemView.setScaleX(1f); // a recycled tile may still carry the focus zoom
		h.itemView.setScaleY(1f);
		if (t.image != null) {
			h.image.setScaleType(ImageView.ScaleType.CENTER_CROP);
			Glide.with(h.image).load(t.image).into(h.image);
		} else {
			Glide.with(h.image).clear(h.image);
			h.image.setScaleType(ImageView.ScaleType.CENTER);
			h.image.setImageResource(t.icon);
		}
		h.label.setText(t.label);
		h.label.setVisibility(t.label == null ? View.GONE : View.VISIBLE);
		h.heart.setVisibility(t.postId >= 0 && Likes.has(t.postId) ? View.VISIBLE : View.GONE);
		h.itemView.setContentDescription(t.label != null ? t.label : "Post");
		h.itemView.setOnClickListener(v -> t.click.run());
	}

	@Override
	public int getItemCount() {
		return tiles.size();
	}
}