implement new attachment UI with buttons to copy URL/view separate

attachment
This commit is contained in:
Andrew Dolgov 2012-03-12 14:57:57 +03:00
parent 7da5405c3f
commit 8caa0fcd82
18 changed files with 423 additions and 34 deletions

View File

@ -102,4 +102,32 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" /> android:layout_weight="1" />
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -98,7 +98,6 @@
</LinearLayout> </LinearLayout>
<TextView <TextView
android:id="@+id/content" android:id="@+id/content"
android:text="Article content" android:text="Article content"
@ -106,4 +105,31 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" /> android:layout_weight="1" />
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -105,4 +105,32 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" /> android:layout_weight="1" />
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -109,4 +109,32 @@
android:padding="3dip" > android:padding="3dip" >
</TextView> </TextView>
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -107,4 +107,32 @@
android:padding="3dip" > android:padding="3dip" >
</TextView> </TextView>
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -107,4 +107,32 @@
android:padding="3dip" > android:padding="3dip" >
</TextView> </TextView>
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -48,10 +48,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@+id/linearLayout3" android:layout_above="@+id/linearLayout3"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:textSize="15sp"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_weight="1" android:layout_weight="1"
android:text="There are many variations of passages of Lorem Ipsum available" /> android:text="There are many variations of passages of Lorem Ipsum available"
android:textSize="15sp" />
<TextView <TextView
android:id="@+id/tags" android:id="@+id/tags"
@ -76,7 +76,6 @@
android:text="{DATE}" android:text="{DATE}"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="10sp" /> android:textSize="10sp" />
</RelativeLayout> </RelativeLayout>
<ImageView <ImageView
@ -94,6 +93,34 @@
android:layout_weight="1" android:layout_weight="1"
android:padding="3dip" > android:padding="3dip" >
</WebView> </WebView>
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -109,4 +109,32 @@
android:padding="3dip" > android:padding="3dip" >
</TextView> </TextView>
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -107,4 +107,32 @@
android:padding="3dip" > android:padding="3dip" >
</TextView> </TextView>
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -107,4 +107,31 @@
android:padding="3dip" > android:padding="3dip" >
</TextView> </TextView>
<LinearLayout
android:id="@+id/attachments_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" >
<Spinner
android:id="@+id/attachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:prompt="@string/attachments_prompt" />
<Button
android:id="@+id/attachment_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_view" />
<Button
android:id="@+id/attachment_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="@string/attachment_copy" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -129,4 +129,7 @@
<string name="tablet_article_swipe">Swipe between articles</string> <string name="tablet_article_swipe">Swipe between articles</string>
<string name="article_link_copy">Copy link to clipboard</string> <string name="article_link_copy">Copy link to clipboard</string>
<string name="text_copied_to_clipboard">Text copied to clipboard</string> <string name="text_copied_to_clipboard">Text copied to clipboard</string>
<string name="attachments_prompt">Select attachment</string>
<string name="attachment_view">View</string>
<string name="attachment_copy">Copy URL</string>
</resources> </resources>

View File

@ -4,6 +4,7 @@ import java.io.File;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
@ -12,7 +13,10 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
@ -23,11 +27,17 @@ import android.util.TypedValue;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.webkit.WebSettings; import android.webkit.WebSettings;
import android.webkit.WebView; import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.AdapterContextMenuInfo;
public class ArticleFragment extends Fragment { public class ArticleFragment extends Fragment {
@ -178,8 +188,15 @@ public class ArticleFragment extends Fragment {
"</head>" + "</head>" +
"<body>" + articleContent; "<body>" + articleContent;
final Spinner spinner = (Spinner) view.findViewById(R.id.attachments);
if (m_article.attachments != null && m_article.attachments.size() != 0) { if (m_article.attachments != null && m_article.attachments.size() != 0) {
String attachments = "<div class=\"attachments\">" + getString(R.string.attachments) + " "; ArrayList<Attachment> spinnerArray = new ArrayList<Attachment>();
ArrayAdapter<Attachment> spinnerArrayAdapter = new ArrayAdapter<Attachment>(
getActivity(), android.R.layout.simple_spinner_item, spinnerArray);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
for (Attachment a : m_article.attachments) { for (Attachment a : m_article.attachments) {
if (a.content_type != null && a.content_url != null) { if (a.content_type != null && a.content_url != null) {
@ -187,13 +204,11 @@ public class ArticleFragment extends Fragment {
try { try {
URL url = new URL(a.content_url.trim()); URL url = new URL(a.content_url.trim());
String atitle = (a.title != null && a.title.length() > 0) ? a.title : new File(url.getFile()).getName();
if (a.content_type.indexOf("image") != -1) { if (a.content_type.indexOf("image") != -1) {
content += "<br/><img src=\"" + url.toString().trim().replace("\"", "\\\"") + "\">"; content += "<br/><img src=\"" + url.toString().trim().replace("\"", "\\\"") + "\">";
} }
attachments += "<a href=\""+url.toString().trim().replace("\"", "\\\"") + "\">" + atitle + "</a>, "; spinnerArray.add(a);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
// //
@ -203,8 +218,38 @@ public class ArticleFragment extends Fragment {
} }
} }
content += attachments.replaceAll(", $", "");
content += "</div>"; spinner.setAdapter(spinnerArrayAdapter);
Button attachmentsView = (Button) view.findViewById(R.id.attachment_view);
attachmentsView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Attachment attachment = (Attachment) spinner.getSelectedItem();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(attachment.content_url));
startActivity(browserIntent);
}
});
Button attachmentsCopy = (Button) view.findViewById(R.id.attachment_copy);
attachmentsCopy.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Attachment attachment = (Attachment) spinner.getSelectedItem();
if (attachment != null) {
m_onlineServices.copyToClipboard(attachment.content_url);
}
}
});
} else {
view.findViewById(R.id.attachments_holder).setVisibility(View.GONE);
} }
content += "</body></html>"; content += "</body></html>";

View File

@ -1,5 +1,9 @@
package org.fox.ttrss; package org.fox.ttrss;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
@ -30,6 +34,19 @@ public class Attachment implements Parcelable {
out.writeInt(post_id); out.writeInt(post_id);
} }
public String toString() {
if (title != null && title.length() > 0) {
return title;
} else {
try {
URL url = new URL(content_url.trim());
return new File(url.getFile()).getName();
} catch (MalformedURLException e) {
return content_url;
}
}
}
public void readFromParcel(Parcel in) { public void readFromParcel(Parcel in) {
id = in.readInt(); id = in.readInt();
content_url = in.readString(); content_url = in.readString();

View File

@ -16,9 +16,11 @@ import org.jsoup.Jsoup;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
@ -38,9 +40,11 @@ import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -444,34 +448,67 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
if (m_combinedMode) { if (m_combinedMode) {
content.setMovementMethod(LinkMovementMethod.getInstance()); content.setMovementMethod(LinkMovementMethod.getInstance());
if (article.attachments != null && article.attachments.size() != 0) { final Spinner spinner = (Spinner) v.findViewById(R.id.attachments);
String attachments = "<div style=\"font-size : 70%; margin-top : 1em;\">" + getString(R.string.attachments) + " ";
ArrayList<Attachment> spinnerArray = new ArrayList<Attachment>();
ArrayAdapter<Attachment> spinnerArrayAdapter = new ArrayAdapter<Attachment>(
getActivity(), android.R.layout.simple_spinner_item, spinnerArray);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
if (article.attachments != null && article.attachments.size() != 0) {
for (Attachment a : article.attachments) { for (Attachment a : article.attachments) {
if (a.content_type != null && a.content_url != null) { if (a.content_type != null && a.content_url != null) {
try { try {
URL url = new URL(a.content_url.trim()); URL url = new URL(a.content_url.trim());
String atitle = (a.title != null && a.title.length() > 0) ? a.title : new File(url.getFile()).getName();
if (a.content_type.indexOf("image") != -1) { if (a.content_type.indexOf("image") != -1) {
articleContent += "<br/><img src=\"" + url.toString().trim().replace("\"", "\\\"") + "\">"; articleContent += "<br/><img src=\"" + url.toString().trim().replace("\"", "\\\"") + "\">";
} }
attachments += "<a href=\""+url.toString().trim().replace("\"", "\\\"") + "\">" + atitle + "</a>, "; spinnerArray.add(a);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
// //
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
articleContent += attachments.replaceAll(", $", "");
articleContent += "</div>";
spinner.setAdapter(spinnerArrayAdapter);
Button attachmentsView = (Button) v.findViewById(R.id.attachment_view);
attachmentsView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Attachment attachment = (Attachment) spinner.getSelectedItem();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(attachment.content_url));
startActivity(browserIntent);
}
});
Button attachmentsCopy = (Button) v.findViewById(R.id.attachment_copy);
attachmentsCopy.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Attachment attachment = (Attachment) spinner.getSelectedItem();
if (attachment != null) {
m_onlineServices.copyToClipboard(attachment.content_url);
}
}
});
} else {
v.findViewById(R.id.attachments_holder).setVisibility(View.GONE);
} }
//content.setText(Html.fromHtml(article.content, new URLImageGetter(content, getActivity()), null)); //content.setText(Html.fromHtml(article.content, new URLImageGetter(content, getActivity()), null));
@ -491,6 +528,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener,
} else { } else {
content.setVisibility(View.GONE); content.setVisibility(View.GONE);
v.findViewById(R.id.attachments_holder).setVisibility(View.GONE);
} }
} }

View File

@ -1829,17 +1829,7 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
} }
if (article != null) { if (article != null) {
if (android.os.Build.VERSION.SDK_INT < 11) { copyToClipboard(article.link);
@SuppressWarnings("deprecation")
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboard.setText(article.link);
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboard.setText(article.link);
}
Toast toast = Toast.makeText(MainActivity.this, R.string.text_copied_to_clipboard, Toast.LENGTH_SHORT);
toast.show();
} }
} }
return true; return true;
@ -2088,4 +2078,19 @@ public class MainActivity extends FragmentActivity implements OnlineServices {
m_selectedArticle = article; m_selectedArticle = article;
updateHeadlines(); updateHeadlines();
} }
@Override
public void copyToClipboard(String str) {
if (android.os.Build.VERSION.SDK_INT < 11) {
@SuppressWarnings("deprecation")
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboard.setText(str);
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
clipboard.setText(str);
}
Toast toast = Toast.makeText(MainActivity.this, R.string.text_copied_to_clipboard, Toast.LENGTH_SHORT);
toast.show();
}
} }

View File

@ -165,6 +165,8 @@ public class OfflineArticleFragment extends Fragment {
articleContent = doc.toString(); articleContent = doc.toString();
} }
view.findViewById(R.id.attachments_holder).setVisibility(View.GONE);
switch (Integer.parseInt(m_prefs.getString("font_size", "0"))) { switch (Integer.parseInt(m_prefs.getString("font_size", "0"))) {
case 0: case 0:
cssOverride += "body { text-align : justify; font-size : 14px; } "; cssOverride += "body { text-align : justify; font-size : 14px; } ";

View File

@ -371,9 +371,10 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis
} else { } else {
content.setVisibility(View.GONE); content.setVisibility(View.GONE);
} }
} }
v.findViewById(R.id.attachments_holder).setVisibility(View.GONE);
TextView dv = (TextView) v.findViewById(R.id.date); TextView dv = (TextView) v.findViewById(R.id.date);
if (dv != null) { if (dv != null) {

View File

@ -24,5 +24,7 @@ public interface OnlineServices {
public boolean getUnreadOnly(); public boolean getUnreadOnly();
public int getApiLevel(); public int getApiLevel();
public void setSelectedArticle(Article article); public void setSelectedArticle(Article article);
public void copyToClipboard(String str);
} }