content: package allen.town.podcast.view;
  
  import android.content.ClipData;
  import android.content.ClipboardManager;
  import android.content.Context;
  import android.content.Intent;
  import android.graphics.Color;
  import android.net.Uri;
  import android.os.Build;
  import android.util.AttributeSet;
  import android.util.Log;
  import android.view.ContextMenu;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.View;
  import android.webkit.WebSettings;
  import android.webkit.WebView;
  import android.webkit.WebViewClient;
  import android.widget.Toast;
  
  import androidx.core.content.ContextCompat;
  import androidx.core.util.Consumer;
  
  import allen.town.focus_common.util.TopSnackbarUtil;
  import allen.town.podcast.R;
  import allen.town.podcast.activity.MainActivity;
  import allen.town.podcast.core.util.menuhandler.MenuItemUtils;
  import allen.town.podcast.core.util.Converter;
  import allen.town.podcast.core.util.IntentUtils;
  import allen.town.podcast.core.util.NetworkUtils;
  import allen.town.podcast.core.util.ShareUtils;
  import allen.town.podcast.core.util.playback.Timeline;
  import me.zhanghai.android.fastscroll.FastScrollWebView;
  
  public class PodWebView extends WebView implements View.OnLongClickListener {
      private static final String TAG = "PodWebView";
  
      /**
       * URL that was selected via long-press.
       */
      private String selectedUrl;
      private Consumer<Integer> timecodeSelectedListener;
      private Runnable pageFinishedListener;
  
      public PodWebView(Context context) {
          super(context);
          setup();
      }
  
      public PodWebView(Context context, AttributeSet attrs) {
          super(context, attrs);
          setup();
      }
  
      public PodWebView(Context context, AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
          setup();
      }
  
      private void setup() {
          setBackgroundColor(Color.TRANSPARENT);
          if (!NetworkUtils.networkAvailable()) {
              getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
              // Use cached resources, even if they have expired
          }
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
              getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
          }
          getSettings().setUseWideViewPort(false);
          getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
          getSettings().setLoadWithOverviewMode(true);
          setOnLongClickListener(this);
  
          setWebViewClient(new WebViewClient() {
              @Override
              public boolean shouldOverrideUrlLoading(WebView view, String url) {
                  if (Timeline.isTimecodeLink(url) && timecodeSelectedListener != null) {
                      timecodeSelectedListener.accept(Timeline.getTimecodeLinkTime(url));
                  } else {
                      IntentUtils.openInBrowser(getContext(), url);
                  }
                  return true;
              }
  
              @Override
              public void onPageFinished(WebView view, String url) {
                  super.onPageFinished(view, url);
                  Log.d(TAG, "page finished");
                  if (pageFinishedListener != null) {
                      pageFinishedListener.run();
                  }
              }
          });
      }
  
      @Override
      public boolean onLongClick(View v) {
          WebView.HitTestResult r = getHitTestResult();
          if (r != null && r.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
              selectedUrl = r.getExtra();
              showContextMenu();
              return true;
          } else if (r != null && r.getType() == HitTestResult.EMAIL_TYPE) {
              ClipboardManager clipboardManager = ContextCompat.getSystemService(this.getContext(),
                                                                                 ClipboardManager.class);
              if (clipboardManager != null) {
                  clipboardManager.setPrimaryClip(ClipData.newPlainText("FocusPodcast", r.getExtra()));
              }
              if (this.getContext() instanceof MainActivity) {
                  if (Build.VERSION.SDK_INT <= 32) {
                      TopSnackbarUtil.showSnack(this.getContext(), getResources().getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT);
                  }
              }
              return true;
          }
          selectedUrl = null;
          return false;
      }
  
      public boolean onContextItemSelected(MenuItem item) {
          if (selectedUrl == null) {
              return false;
          }
  
          final int itemId = item.getItemId();
          if (itemId == R.id.open_in_browser_item) {
              IntentUtils.openInBrowser(getContext(), selectedUrl);
          } else if (itemId == R.id.share_url_item) {
              ShareUtils.shareLink(getContext(), selectedUrl);
          } else if (itemId == R.id.copy_url_item) {
              ClipData clipData = ClipData.newPlainText(selectedUrl, selectedUrl);
              ClipboardManager cm = (ClipboardManager) getContext()
                      .getSystemService(Context.CLIPBOARD_SERVICE);
              cm.setPrimaryClip(clipData);
              TopSnackbarUtil.showSnack(this.getContext(),R.string.copied_url_msg, Toast.LENGTH_LONG);
          } else if (itemId == R.id.go_to_position_item) {
              if (Timeline.isTimecodeLink(selectedUrl) && timecodeSelectedListener != null) {
                  timecodeSelectedListener.accept(Timeline.getTimecodeLinkTime(selectedUrl));
              } else {
                  Log.e(TAG, "Selected go_to_position_item, but URL was no timecode link: " + selectedUrl);
              }
          } else {
              selectedUrl = null;
              return false;
          }
          selectedUrl = null;
          return true;
      }
  
      @Override
      protected void onCreateContextMenu(ContextMenu menu) {
          super.onCreateContextMenu(menu);
          if (selectedUrl == null) {
              return;
          }
  
          if (Timeline.isTimecodeLink(selectedUrl)) {
              menu.add(Menu.NONE, R.id.go_to_position_item, Menu.NONE, R.string.go_to_position_label);
              menu.setHeaderTitle(Converter.getDurationStringLong(Timeline.getTimecodeLinkTime(selectedUrl)));
          } else {
              Uri uri = Uri.parse(selectedUrl);
              final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
              if (IntentUtils.isCallable(getContext(), intent)) {
                  menu.add(Menu.NONE, R.id.open_in_browser_item, Menu.NONE, R.string.open_in_browser_label);
              }
              menu.add(Menu.NONE, R.id.copy_url_item, Menu.NONE, R.string.copy_url_label);
              menu.add(Menu.NONE, R.id.share_url_item, Menu.NONE, R.string.share_url_label);
              menu.setHeaderTitle(selectedUrl);
          }
          MenuItemUtils.setOnClickListeners(menu, this::onContextItemSelected);
      }
  
      public void setTimecodeSelectedListener(Consumer<Integer> timecodeSelectedListener) {
          this.timecodeSelectedListener = timecodeSelectedListener;
      }
  
      public void setPageFinishedListener(Runnable pageFinishedListener) {
          this.pageFinishedListener = pageFinishedListener;
      }
  
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          setMeasuredDimension(Math.max(getMeasuredWidth(), getMinimumWidth()),
                  Math.max(getMeasuredHeight(), getMinimumHeight()));
      }
  }
  