That fuck shit the fascists are using
1package org.tm.archive.logsubmit;
2
3import android.content.Context;
4import android.view.LayoutInflater;
5import android.view.View;
6import android.view.ViewGroup;
7import android.widget.TextView;
8
9import androidx.annotation.NonNull;
10import androidx.core.content.ContextCompat;
11import androidx.recyclerview.widget.RecyclerView;
12
13import org.signal.paging.PagingController;
14import org.tm.archive.R;
15import org.tm.archive.components.ListenableHorizontalScrollView;
16
17import java.util.ArrayList;
18import java.util.List;
19import java.util.concurrent.CopyOnWriteArrayList;
20
21public class SubmitDebugLogAdapter extends RecyclerView.Adapter<SubmitDebugLogAdapter.LineViewHolder> {
22
23 private static final int LINE_LENGTH = 500;
24
25 private static final int TYPE_LOG = 1;
26 private static final int TYPE_PLACEHOLDER = 2;
27
28 private final ScrollManager scrollManager;
29 private final Listener listener;
30 private final PagingController pagingController;
31 private final List<LogLine> lines;
32
33 private boolean editing;
34
35 public SubmitDebugLogAdapter(@NonNull Listener listener, @NonNull PagingController pagingController) {
36 this.listener = listener;
37 this.pagingController = pagingController;
38 this.scrollManager = new ScrollManager();
39 this.lines = new ArrayList<>();
40
41 setHasStableIds(true);
42 }
43
44 @Override
45 public long getItemId(int position) {
46 LogLine item = getItem(position);
47 return item != null ? getItem(position).getId() : -1;
48 }
49
50 @Override
51 public int getItemViewType(int position) {
52 return getItem(position) == null ? TYPE_PLACEHOLDER : TYPE_LOG;
53 }
54
55 protected LogLine getItem(int position) {
56 pagingController.onDataNeededAroundIndex(position);
57 return lines.get(position);
58 }
59
60 public void submitList(@NonNull List<LogLine> list) {
61 this.lines.clear();
62 this.lines.addAll(list);
63 notifyDataSetChanged();
64 }
65
66 @Override
67 public int getItemCount() {
68 return lines.size();
69 }
70
71 @Override
72 public @NonNull LineViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
73 return new LineViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.submit_debug_log_line_item, parent, false));
74 }
75
76 @Override
77 public void onBindViewHolder(@NonNull LineViewHolder holder, int position) {
78 LogLine item = getItem(position);
79
80 if (item == null) {
81 item = SimpleLogLine.EMPTY;
82 }
83
84 holder.bind(item, LINE_LENGTH, editing, scrollManager, listener);
85 }
86
87 @Override
88 public void onViewRecycled(@NonNull LineViewHolder holder) {
89 holder.unbind(scrollManager);
90 }
91
92 public void setEditing(boolean editing) {
93 this.editing = editing;
94 notifyDataSetChanged();
95 }
96
97 private static class ScrollManager {
98 private final List<ScrollObserver> listeners = new CopyOnWriteArrayList<>();
99
100 private int currentPosition;
101
102 void subscribe(@NonNull ScrollObserver observer) {
103 listeners.add(observer);
104 observer.onScrollChanged(currentPosition);
105 }
106
107 void unsubscribe(@NonNull ScrollObserver observer) {
108 listeners.remove(observer);
109 }
110
111 void notify(int position) {
112 currentPosition = position;
113
114 for (ScrollObserver listener : listeners) {
115 listener.onScrollChanged(position);
116 }
117 }
118 }
119
120 private interface ScrollObserver {
121 void onScrollChanged(int position);
122 }
123
124 interface Listener {
125 void onLogDeleted(@NonNull LogLine logLine);
126 }
127
128 static class LineViewHolder extends RecyclerView.ViewHolder implements ScrollObserver {
129
130 private final TextView text;
131 private final ListenableHorizontalScrollView scrollView;
132
133 LineViewHolder(@NonNull View itemView) {
134 super(itemView);
135 this.text = itemView.findViewById(R.id.log_item_text);
136 this.scrollView = itemView.findViewById(R.id.log_item_scroll);
137 }
138
139 void bind(@NonNull LogLine line, int longestLine, boolean editing, @NonNull ScrollManager scrollManager, @NonNull Listener listener) {
140 Context context = itemView.getContext();
141
142 if (line.getText().length() > longestLine) {
143 text.setText(line.getText().substring(0, longestLine));
144 } else if (line.getText().length() < longestLine) {
145 text.setText(padRight(line.getText(), longestLine));
146 } else {
147 text.setText(line.getText());
148 }
149
150 switch (line.getStyle()) {
151 case NONE: text.setTextColor(ContextCompat.getColor(context, R.color.debuglog_color_none)); break;
152 case VERBOSE: text.setTextColor(ContextCompat.getColor(context, R.color.debuglog_color_verbose)); break;
153 case DEBUG: text.setTextColor(ContextCompat.getColor(context, R.color.debuglog_color_debug)); break;
154 case INFO: text.setTextColor(ContextCompat.getColor(context, R.color.debuglog_color_info)); break;
155 case WARNING: text.setTextColor(ContextCompat.getColor(context, R.color.debuglog_color_warn)); break;
156 case ERROR: text.setTextColor(ContextCompat.getColor(context, R.color.debuglog_color_error)); break;
157 }
158
159 scrollView.setOnScrollListener((newLeft, oldLeft) -> {
160 if (oldLeft - newLeft != 0) {
161 scrollManager.notify(newLeft);
162 }
163 });
164
165 scrollManager.subscribe(this);
166
167 if (editing) {
168 text.setOnClickListener(v -> listener.onLogDeleted(line));
169 } else {
170 text.setOnClickListener(null);
171 }
172 }
173
174 void unbind(@NonNull ScrollManager scrollManager) {
175 text.setOnClickListener(null);
176 scrollManager.unsubscribe(this);
177 }
178
179 @Override
180 public void onScrollChanged(int position) {
181 scrollView.scrollTo(position, 0);
182 }
183
184 private static String padRight(String s, int n) {
185 return String.format("%-" + n + "s", s);
186 }
187 }
188}